diff --git a/server/dbdata/tables.go b/server/dbdata/tables.go
index bdd446b..eeb8cb4 100644
--- a/server/dbdata/tables.go
+++ b/server/dbdata/tables.go
@@ -60,6 +60,7 @@ type IpMap struct {
 	Id        int       `json:"id" xorm:"pk autoincr not null"`
 	IpAddr    string    `json:"ip_addr" xorm:"varchar(32) not null unique"`
 	MacAddr   string    `json:"mac_addr" xorm:"varchar(32) not null unique"`
+	UniqueMac bool      `json:"unique_mac" xorm:"Bool index"`
 	Username  string    `json:"username" xorm:"varchar(60)"`
 	Keep      bool      `json:"keep" xorm:"Bool"` // 保留 ip-mac 绑定
 	KeepTime  time.Time `json:"keep_time" xorm:"DateTime"`
diff --git a/server/handler/link_auth.go b/server/handler/link_auth.go
index 63f8023..fee85b0 100644
--- a/server/handler/link_auth.go
+++ b/server/handler/link_auth.go
@@ -18,6 +18,10 @@ import (
 var profileHash = ""
 
 func LinkAuth(w http.ResponseWriter, r *http.Request) {
+	// TODO 调试信息输出
+	//hd, _ := httputil.DumpRequest(r, true)
+	//base.Debug("DumpRequest: ", string(hd))
+
 	// 判断anyconnect客户端
 	userAgent := strings.ToLower(r.UserAgent())
 	xAggregateAuth := r.Header.Get("X-Aggregate-Auth")
@@ -106,6 +110,7 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) {
 	sess.PlatformVersion = ua.PlatformVersion
 	sess.RemoteAddr = r.RemoteAddr
 	// 获取客户端mac地址
+	sess.UniqueMac = true
 	macHw, err := net.ParseMAC(sess.MacAddr)
 	if err != nil {
 		var sum [16]byte
@@ -113,6 +118,7 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) {
 			sum = md5.Sum([]byte(sess.UniqueIdGlobal))
 		} else {
 			sum = md5.Sum([]byte(sess.Token))
+			sess.UniqueMac = false
 		}
 		macHw = sum[0:5] // 5个byte
 		macHw = append([]byte{0x02}, macHw...)
diff --git a/server/handler/link_tunnel.go b/server/handler/link_tunnel.go
index bcefe18..7128a4c 100644
--- a/server/handler/link_tunnel.go
+++ b/server/handler/link_tunnel.go
@@ -34,9 +34,8 @@ func HttpAddHeader(w http.ResponseWriter, key string, value string) {
 
 func LinkTunnel(w http.ResponseWriter, r *http.Request) {
 	// TODO 调试信息输出
-	// hd, _ := httputil.DumpRequest(r, true)
-	// fmt.Println("DumpRequest: ", string(hd))
-	// fmt.Println("LinkTunnel", r.RemoteAddr)
+	//hd, _ := httputil.DumpRequest(r, true)
+	//base.Debug("DumpRequest: ", string(hd))
 
 	// 判断session-token的值
 	cookie, err := r.Cookie("webvpn")
diff --git a/server/handler/server.go b/server/handler/server.go
index 356d7a7..c4c4cee 100644
--- a/server/handler/server.go
+++ b/server/handler/server.go
@@ -66,7 +66,7 @@ func startTls() {
 	if base.Cfg.ProxyProtocol {
 		ln = &proxyproto.Listener{
 			Listener:          ln,
-			ReadHeaderTimeout: 20 * time.Second,
+			ReadHeaderTimeout: 40 * time.Second,
 		}
 	}
 
diff --git a/server/sessdata/ip_pool.go b/server/sessdata/ip_pool.go
index 1ab5ae2..170d58b 100644
--- a/server/sessdata/ip_pool.go
+++ b/server/sessdata/ip_pool.go
@@ -64,7 +64,8 @@ func getIpLease() {
 	xdb := dbdata.GetXdb()
 	keepIpMaps := []dbdata.IpMap{}
 	sNow := time.Now().Add(-1 * time.Duration(base.Cfg.IpLease) * time.Second)
-	err := xdb.Cols("ip_addr").Where("keep=?", true).Or("last_login>?", sNow).Find(&keepIpMaps)
+	err := xdb.Cols("ip_addr").Where("keep=?", true).
+		Or("unique_mac=? and last_login>?", true, sNow).Find(&keepIpMaps)
 	if err != nil {
 		base.Error(err)
 	}
@@ -78,33 +79,71 @@ func getIpLease() {
 }
 
 // AcquireIp 获取动态ip
-func AcquireIp(username, macAddr string) net.IP {
+func AcquireIp(username, macAddr string, uniqueMac bool) net.IP {
 	ipPoolMux.Lock()
 	defer ipPoolMux.Unlock()
 
-	tNow := time.Now()
+	var (
+		err  error
+		tNow = time.Now()
+		sNow = time.Now().Add(-1 * time.Duration(base.Cfg.IpLease) * time.Second)
+	)
 
-	// 判断是否已经分配过
-	mi := &dbdata.IpMap{}
-	err := dbdata.One("mac_addr", macAddr, mi)
-	// 存在ip记录
-	if err == nil {
-		ipStr := mi.IpAddr
-		ip := net.ParseIP(ipStr)
-		// 跳过活跃连接
-		_, ok := ipActive[ipStr]
-		// 检测原有ip是否在新的ip池内
-		if IpPool.Ipv4IPNet.Contains(ip) && !ok &&
-			utils.Ip2long(ip) >= IpPool.IpLongMin &&
-			utils.Ip2long(ip) <= IpPool.IpLongMax {
-			mi.Username = username
-			mi.LastLogin = tNow
-			// 回写db数据
-			_ = dbdata.Set(mi)
-			ipActive[ipStr] = true
-			return ip
+	if uniqueMac {
+		// 判断是否已经分配过
+		mi := &dbdata.IpMap{}
+		err = dbdata.One("mac_addr", macAddr, mi)
+		// 存在ip记录
+		if err == nil {
+			ipStr := mi.IpAddr
+			ip := net.ParseIP(ipStr)
+			// 跳过活跃连接
+			_, ok := ipActive[ipStr]
+			// 检测原有ip是否在新的ip池内
+			if IpPool.Ipv4IPNet.Contains(ip) && !ok &&
+				utils.Ip2long(ip) >= IpPool.IpLongMin &&
+				utils.Ip2long(ip) <= IpPool.IpLongMax {
+				mi.Username = username
+				mi.LastLogin = tNow
+				mi.UniqueMac = uniqueMac
+				// 回写db数据
+				_ = dbdata.Set(mi)
+				ipActive[ipStr] = true
+				return ip
+			}
+			_ = dbdata.Del(mi)
+		}
+	} else {
+		ipMaps := []dbdata.IpMap{}
+		err = dbdata.FindWhere(&ipMaps, 50, 1, "username=? and unique_mac=?", username, false)
+		if err == nil {
+			//遍历mac记录
+			for _, mi := range ipMaps {
+				ipStr := mi.IpAddr
+				ip := net.ParseIP(ipStr)
+
+				// 跳过活跃连接
+				if _, ok := ipActive[ipStr]; ok {
+					continue
+				}
+				// 跳过ip租期内数据
+				if _, ok := ipLease[ipStr]; ok {
+					continue
+				}
+
+				if IpPool.Ipv4IPNet.Contains(ip) &&
+					utils.Ip2long(ip) >= IpPool.IpLongMin &&
+					utils.Ip2long(ip) <= IpPool.IpLongMax {
+					mi.LastLogin = tNow
+					mi.MacAddr = macAddr
+					mi.UniqueMac = uniqueMac
+					// 回写db数据
+					_ = dbdata.Set(mi)
+					ipActive[ipStr] = true
+					return ip
+				}
+			}
 		}
-		_ = dbdata.Del(mi)
 	}
 
 	// 全局遍历超过租期和未保留的ip
@@ -121,16 +160,22 @@ func AcquireIp(username, macAddr string) net.IP {
 			continue
 		}
 
-		v := &dbdata.IpMap{}
-		err = dbdata.One("ip_addr", ipStr, v)
-		if err == nil {
-			// 存在记录直接跳过
-			continue
+		mi := &dbdata.IpMap{}
+		err = dbdata.One("ip_addr", ipStr, mi)
+		if err == nil && mi.LastLogin.Before(sNow) {
+			// 存在记录,说明已经超过租期,可以直接使用
+			mi.LastLogin = tNow
+			mi.MacAddr = macAddr
+			mi.UniqueMac = uniqueMac
+			// 回写db数据
+			_ = dbdata.Set(mi)
+			ipActive[ipStr] = true
+			return ip
 		}
 
 		if dbdata.CheckErrNotFound(err) {
 			// 该ip没有被使用
-			mi = &dbdata.IpMap{IpAddr: ipStr, MacAddr: macAddr, Username: username, LastLogin: tNow}
+			mi := &dbdata.IpMap{IpAddr: ipStr, MacAddr: macAddr, UniqueMac: uniqueMac, Username: username, LastLogin: tNow}
 			_ = dbdata.Add(mi)
 			ipActive[ipStr] = true
 			return ip
diff --git a/server/sessdata/online.go b/server/sessdata/online.go
index e8dff7a..7ac526d 100644
--- a/server/sessdata/online.go
+++ b/server/sessdata/online.go
@@ -14,6 +14,7 @@ type Online struct {
 	Username         string    `json:"username"`
 	Group            string    `json:"group"`
 	MacAddr          string    `json:"mac_addr"`
+	UniqueMac        bool      `json:"unique_mac"`
 	Ip               net.IP    `json:"ip"`
 	RemoteAddr       string    `json:"remote_addr"`
 	TunName          string    `json:"tun_name"`
@@ -52,6 +53,7 @@ func OnlineSess() []Online {
 				Username:         v.Username,
 				Group:            v.Group,
 				MacAddr:          v.MacAddr,
+				UniqueMac:        v.UniqueMac,
 				RemoteAddr:       v.CSess.RemoteAddr,
 				TunName:          v.CSess.IfName,
 				Mtu:              v.CSess.Mtu,
diff --git a/server/sessdata/session.go b/server/sessdata/session.go
index 6af9bc5..b60675f 100644
--- a/server/sessdata/session.go
+++ b/server/sessdata/session.go
@@ -71,6 +71,7 @@ type Session struct {
 	MacAddr         string // 客户端mac地址
 	UniqueIdGlobal  string // 客户端唯一标示
 	MacHw           net.HardwareAddr
+	UniqueMac       bool   // 客户端获取到真实设备mac
 	Username        string // 用户名
 	Group           string
 	AuthStep        string
@@ -178,6 +179,7 @@ func (s *Session) NewConn() *ConnSession {
 	macAddr := s.MacAddr
 	macHw := s.MacHw
 	username := s.Username
+	uniqueMac := s.UniqueMac
 	s.mux.RUnlock()
 	if active {
 		s.CSess.Close()
@@ -187,7 +189,7 @@ func (s *Session) NewConn() *ConnSession {
 	if !limit {
 		return nil
 	}
-	ip := AcquireIp(username, macAddr)
+	ip := AcquireIp(username, macAddr, uniqueMac)
 	if ip == nil {
 		LimitClient(username, true)
 		return nil
diff --git a/web/src/pages/user/IpMap.vue b/web/src/pages/user/IpMap.vue
index b6f6076..d4f7275 100644
--- a/web/src/pages/user/IpMap.vue
+++ b/web/src/pages/user/IpMap.vue
@@ -35,6 +35,14 @@
             label="MAC地址">
         </el-table-column>
 
+        <el-table-column
+            prop="unique_mac"
+            label="唯一MAC">
+            <template slot-scope="scope">
+                <el-tag v-if="scope.row.unique_mac" type="success">是</el-tag>
+            </template>
+        </el-table-column>
+
         <el-table-column
             prop="username"
             label="用户名">
diff --git a/web/src/pages/user/Online.vue b/web/src/pages/user/Online.vue
index f9041cb..9b4f141 100644
--- a/web/src/pages/user/Online.vue
+++ b/web/src/pages/user/Online.vue
@@ -27,6 +27,15 @@
             prop="mac_addr"
             label="MAC地址">
         </el-table-column>
+        
+        <el-table-column
+            prop="unique_mac"
+            label="唯一MAC">
+            <template slot-scope="scope">
+                <el-tag v-if="scope.row.unique_mac" type="success">是</el-tag>
+            </template>
+        </el-table-column>
+
         <el-table-column
             prop="ip"
             label="IP地址"