一支红杏出墙来

freeopen 2021-04-04 [奇门遁甲] #vpn

一、准备阶段

新建服务器时,不选择 安全加固

首先卸载阿里云安骑士

wget http://update.aegis.aliyun.com/download/uninstall.sh
source ./uninstall.sh
wget http://update.aegis.aliyun.com/download/quartz_uninstall.sh
source ./quartz_uninstall.sh

删除安骑士残留文件

pkill aliyun-service
rm -fr /etc/init.d/agentwatch /usr/sbin/aliyun-service
rm -rf /usr/local/aegis*

以 root 用户登录, 安装 epel 源,阿里云centos 8 的镜像比较新,不需要 update, 费流量。

dnf install epel-release

安装必备软件

dnf install nginx certbot iptables-services crontab strongswan
#nginx开机启动
systemctl enable nginx
#启动nginx
systemctl restart nginx

二、申请 ssl 证书

StrongSwan IPsec IKEv2 连接需要用到服务器证书,用于验证服务器身份。由于自签发证书不受操作系统信任,我们需要申请 Let’s Encrypt 免费证书。 申请证书需要有域名,提前将域名解析到你的vps地址。

方式一,必须打开nginx, 能访问80端口

#在web根目录创建临时目录
mkdir -p /usr/share/nginx/html/.well-known/acme-challenge
 
#--webroot 参数:指定使用临时目录的方式. -w 参数:指定后面-d 域名所在的根目录, 如果一次申请多个域的, 可以附加更多 -w...-d... 这段.
certbot certonly --webroot --email xxx@xxx.com -w /usr/share/nginx/html -d xx.xxx.com

方式二,不需要打开nginx,能访问80端口

certbot certonly --rsa-key-size 2048 --standalone --agree-tos --no-eff-email --email xxx@gmail.com -d xxx.xxx.com

Certbot 证书自动更新

由于 Let’s Encrypt 证书只有90天有效期,为避免过期,需要启用自动续期。自动续期由定时任务完成。

方案一

编辑定时任务配置, 写入下面红色内容,这段的意思是每月28号凌晨3点运行 certbot renew 命令给证书续期,如果续期成功则重启 nginx 和 strongswan 服务。

vim /etc/crontab

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
 
# For details see man 4 crontabs
 
# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
0 3 28 * * root certbot renew --quiet --deploy-hook "systemctl restart nginx && systemctl restart strongswan"

加载定时任务配置,使之生效。

crontab /etc/crontab

方案二

$ cat /etc/cron.d/certbot

# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc.  Renewal will only occur if expiration
# is within 30 days.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root test -x /usr/bin/certbot  -a \! -d /run/systemd/system &&  perl -e 'sleep int(rand(43200))' &&  certbot -q renew

意思说每天测试一下,证书是否在未来30天过期,如果过期就更新,否则什么也不做。

方案三

安装了certbot nginx 插件后,执行一次证书更新后,发现输出的提示语中有句,certbot证书已能自动更新,仔细查看配置,发现生成了一个证书更新服务,名字叫certbot-renew, 由两个文件组成,certbot-renew.service 和 certbot-renew.timer。基本逻辑是每12小时,检查一下证书更新。

服务并没自动启动,须手动启动这个服务,我目前采用的这个方案。同时在crontab中设置每月指定时间重启一次 strongswan 服务。

systemctl enable --now certbot-renew.timer

注:证书更新后,vpn连接时还是会报错,说证书无效,原因是 strongswan 缓存的是旧的过期证书,重新启动一下 strongswan 即可。编辑 /etc/letsencrypt/renewal/example.com.conf 文件,在最后一行增加,将会在证书更新后,重新启动 strongswan.

renew_hook = systemctl restart strongswan

三、安装 strongswan

注意, 本配置适用于5.8.2以上,基于 swanctl 配置。

vim /etc/strongswan/swanctl/conf.d/xx.xxx.com.conf

connections {
    ikev2-eap-mschapv2 {
        version = 2
        unique = never
        rekey_time = 0s
        fragmentation = yes
        dpd_delay = 60s
        send_cert = always
        pools = ipv4-addrs, ipv6-addrs
        proposals = aes256-sha256-prfsha256-modp2048, aes256gcm16-prfsha384-modp1024, default
        local_addrs = %any
        local {
            certs = cert.pem
            id = xx.xxx.com
        }
        remote {
            auth = eap-mschapv2
            eap_id = %any
        }
        children {
            ikev2-eap-mschapv2 {
                local_ts = 0.0.0.0/0,::/0
                rekey_time = 0s
                dpd_action = clear
                esp_proposals = aes256-sha256, aes128-sha1, default
            }
        }
    }
}
pools {
    ipv4-addrs {
        addrs = 10.10.0.0/24
        dns = 8.8.8.8,8.8.4.4,114.114.114.114
    }
    ipv6-addrs {
        addrs = fec1::0/24
        dns = 2001:4860:4860::8888,2606:4700:4700::1111
    }
}
secrets {
    private-xxx {
        file = privkey.pem
    }   
    eap-user1 {
        id = user1
        secret = "123456"
    }
    eap-user2 {
        id = user2
        secret = "654321"
    }
}

高亮部分中的 xx.xxx.com 替换为上面申请证书时用的域名, private-xxx 中的 xxx 随意,不要有符号,eap-user1 和 id = user1 中的 user1 替换为你想登录vpn使用的账号,secret = “123456” 改为你的密码。 如需添加多个用户,复制 eap-user1 { … } 段粘贴到下面,按上面规则设置新的用户名和密码即可。

安装证书,创建证书软链接到 strongswan 的对应目录。

ln -s /etc/letsencrypt/live/xx.xxx.com/cert.pem /etc/strongswan/swanctl/x509/cert.pem
ln -s /etc/letsencrypt/live/xx.xxx.com/privkey.pem /etc/strongswan/swanctl/private/privkey.pem
ln -s /etc/letsencrypt/live/xx.xxx.com/chain.pem /etc/strongswan/swanctl/x509ca/ca.pem

证书安装完成 重启服务

systemctl restart strongswan

开启内核转发

vim /etc/sysctl.conf

用下面内容替换配置文件中同名的项,如果没有则新增。

#开启内核ipv4转发
net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
 
#开启内核ipv6转发
net.ipv6.conf.all.forwarding = 1

重新加载配置

sysctl -p

配置防火墙

vim /etc/sysconfig/iptables

在合适的位置添加以下规则, 注意顺序, 新增 屏蔽 安骑士 ip 脚本。

# sample configuration for iptables service
# you can edit this manually or use system-config-firewall
# please do not ask us to add additional ports/services to this default configuration
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -s 10.10.0.0/24 -o eth0 -m policy --dir out --pol ipsec -j ACCEPT
-A POSTROUTING -s 10.10.0.0/24 -o eth0 -j MASQUERADE
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -s 140.205.201.0/24 -j DROP
-A INPUT -s 140.205.255.0/24 -j DROP
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -i eth0 -p ah -j ACCEPT
-A INPUT -i eth0 -p esp -j ACCEPT
-A INPUT -i eth0 -p udp -m udp --dport 500 -j ACCEPT
-A INPUT -i eth0 -p udp -m udp --dport 4500 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -i eth0 -m policy --dir in --pol ipsec -j ACCEPT
-A FORWARD -d 10.10.0.0/24 -o eth0 -m policy --dir out --pol ipsec -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

重启防火墙,使规则生效。

systemctl restart iptables

配置strongswan 输出日志,方便测试,测试完成后,关闭该日志

vim /etc/strongswan/strongswan.d/charon.conf

charon {
    filelog {
        charon-debug-log {
            path = /var/log/charon_debug.log
            time_format = %b %e %T
            default = 2
            mgr = 0
            net = 1
            enc = 1
            asn = 1
            job = 1
            ike_name = yes
            append = no
            flush_line = yes
        }
    }
    #这里是其它设置......
}

启动strongswan

systemctl start strongswan

四、最后状态检查 及 测试

systemctl status nginx
systemctl status iptables
systemctl status strongswan

到阿里云控制台打开白名单,包含:

tcp 500
tcp 4500
全部 GRE

windows macos ios 直接配置 vpn即可,

Android 系统需要下载客户端程序,前往官网下载 最新版 apk 程序。 测试完成后,记得关闭 strongswan 日志, 重启 strongswan。

systemctl restart strongswan

设置开机自启动,完工。

systemctl enable iptables
systemctl enable strongswan

五、维护

查看证书情况

certbot certificates

证书手动更新

certbot renew --cert-name domain --dry-run

certbot --nginx certonly -n -d domain

第二种更新方法须安装 python3-certbot-nginx

Back to top