Published on

SSL VPN

Authors

1 SSL-VPN Intro

SSL-VPN支持将本地客户端远程接入 VPC/机房内网 ,使客户端可以安全地访问内网中部署的应用或服务器。

SSL-VPN是在 会话层 通过使用HTTPS的方式实现的,而IPsec-VPN是在 网络层 实现的,能够完成传输层TCPUDP的加密和隧道传输处理

相比IPsec-VPNSSL-VPN数据吞吐量较低,但其不受限于MTU,也不受操作系统和NIC网卡驱动的限制

AliCloud-VPN-Use

应用场景:如公司员工通过SSL-VPN:连接公司内网实现远程办公/访问内网服务器实现本地运维等


2 Fortigate 配置SSL-VPN

2.1 SSL-VPN Settings Demo

port1:有公网IP的网卡,即WAN口 (Fortigate上的 1 个物理端口对应服务器上的一张网卡)

通常 Fortigate 至少会有两张网卡,一张主网卡有公网IP对应WAN口 Port1,一张辅助网卡只有内网·对应LAN口 Port2

主网卡即用于访问外部互联网,辅助网卡一般用于VPC内网互联

SSL-VPN-Settings

2.2 User Group Setting

2.2.1 create user group

User-Group-Settings

少量用户可以通过手动添加用户进入用户组, 大量用户则需要通过脚本自动化导入

查看 FortigateSSL-VPN 统计信息:diagnose vpn ssl statistics

ssl-vpn-maxconn

这里显示最多 5 个用户 68 个连接其实是错的,不知道官方提供这个这个命令的作用


根据 forti 工单回复如下:

You can look up limits in the Maximum Values list, which nowadays is interactive:

https://docs.fortinet.com/max-value-table

For example, a VM0 has a max. number of interfaces of 4K, and a max. no. of IPsec tunnels of 2000.
For This case , a MSL has a max. number of interfaces of 16K, and a max. no. of IPsec tunnels of 40K

Depending on your VM resources, you might exhaust your cpu/ram/bandwidth way before maxing out the total number of allowed ipsec tunnels.

限制SSL-VPN user数量参考


2.2.2 通过脚本导入大量SSL-VPN用户

script as down below:

config user local
    edit "<user1_name>"
        set type password
        set passwd <user1_pwd>
    next
	edit "<user2_name>"
        set type password
        set passwd <user2_pwd>
    next
	.
	.
	.
end

config user group
    edit "SSL_VPN_GROUP"
        set member "<user1_name>,<user2_name>......."
    next
end
Step3: 通过 Scripts 功能上传并运行脚本 run-script
import re

def write_user(file_path, pair_list) -> None:
    """
    写入配置文件。
    Args:
      file_path: 配置文件路径
      pair_list: 用户密码列表
    """

    with open(file_path, "w") as f:
        f.write("config user local\n")
        for pair in pair_list:
            f.write("    edit \"{}""\"\n".format(pair['username']))
            f.write("        set type password\n")
            f.write("        set passwd {}\n".format(pair['password']))
            f.write("    next\n")
        f.write("end\n")


def write_user_group(file_path, pair_list) -> None:
    """
    写入配置文件。
    Args:
      file_path: 配置文件路径
      pair_list: 用户密码列表
    """
    with open(file_path, "a") as f:
        f.write("\nconfig user local\n")
        f.write("    edit \"SSL_VPN_GROUP\"\n")
        f.write("        set member ")
        f.write("\"")
        for i, pair in enumerate(pair_list):
            f.write("{}".format(pair['username']))
            if i != len(pair_list) - 1:
                f.write(",")
        f.write("\"")
        f.write("\n    next\n")
        f.write("end\n")


def format_users(data_source_path) -> list:
    """
    Reads a text file and formats each line in the following pattern:

    "username {password}"

    Args:
      data_source_path: The path to the origin data.

    Returns:
      username password KV list
    """

    with open(data_source_path, "r") as f:
        pattern = r"\s+|,|;"  # 过滤其中的空格、逗号和分号
        result = []
        for line in f:
            pair_map = {}
            match = re.match(r"^(.+)+([\s*,;])+(.+)$", line)  # 两边是任意长度的字符串,中间是任意个空格 逗号或者分号
            print("match", match)
            if match:
                pair_map['username'] = re.sub(pattern, "", str(match.groups()[0]))
                pair_map['password'] = re.sub(pattern, "", str(match.groups()[1]))
                result.append(pair_map)
        print("result length: ", len(result))

    return result


if __name__ == "__main__":
    read_path = "origin.txt"
    res = format_users(read_path)
    write_path = "result.txt"
    write_user(write_path, res)
    write_user_group(write_path, res)

# origin.txt
sunway1, 123456
sunway2, 123456
sunway3, 123456
sunway4, 123456
sunway5, 123456

2.3 Create FireWall Policy

  • 配置 incoming interfacessl-vpn tunnel
  • 配置 outgoing interfaceport2port2是辅助网卡,用于内网互联)

Client ------>SSL-VPN-Tunnel-------> (Fortigate WAN) port1-------->(Fortigate LAN) port2-------> Internal Network

CreateFireWallPolicy

2.4 Testing for Fortigate SSL-VPN

  • 访问 Fortigate Internet ip:10443, 通过ssl vpn中设置好的用户名/密码进行登录

  • 如果 Fortigate 部署在云服务上,则需要配置安全组放行,Fortigate 安全组一般情况下默认全部端口全部协议都放行

UseFortigateSSLVPN

登录后可下载 Forticlient 至本地,使用之前配置的用户名密码连接即可

如果想在登录SSL-VPN时校验更加安全的手机mobile Token: forti token,可以参考:SSL VPN with FortiToken mobile push authentication