一支红杏出墙来

freeopen · 最后更新时间:  [奇门遁甲] #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地址。

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

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

方式二,standalone 模式,不需要打开nginx,但必须能访问80端口

certbot certonly --rsa-key-size 2048 --standalone --agree-tos --no-eff-email --email [email protected] -d xxx.xxx.com

Certbot 证书自动更新

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

对于网站的 SSL 证书, 自动续期也同样重要。

方案一

编辑定时任务配置, 写入下面红色内容,这段的意思是每月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

方案二

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

$ 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

方案三

我最喜欢的方式,采用 centos 模式的 service 进行管理。

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

systemctl enable --now certbot-renew.timer

编辑 /etc/letsencrypt/renewal/example.com.conf 文件,一个域名配置一个文件.

renew_hook = systemctl restart strongswan

或者在 /etc/letsencrypt/renewal-hooks/ 不同目录下配置独立的运行脚本,来运行证书更新后的相关服务。

相关 hook 解释如下, renew_hook 在最新的官方文档中没看到解释,不保证一定可用.

--pre-hook : renew 之前执行
--post-hook : renew 之后执行 
--deploy-hook : renew 成功之后执行

三、安装 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 renew --dry-run

查看证书情况

certbot certificates

证书手动更新

certbot --nginx certonly -n -d domain

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

移除不需要的域名证书

# 先备份
cp /etc/letsencrypt/ /etc/letsencrypt.backup -r
# 再移除,撤销证书并自动删除相关文件
certbot revoke --cert-path /etc/letsencrypt/archive/www.xxxx.com/cert1.pem

六、获取通配符证书

touch /etc/letsencrypt/cloudflare.ini
# Cloudflare API token used by Certbot
dns_cloudflare_api_token = _yourToken_
yum install python3-certbot-dns-cloudflare
certbot certonly  --dns-cloudflare  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini  --key-type ecdsa --domain "*.freeopen.tech"

评论区🔗

你可以在这里快速开始评论,如果 name 填写为 email 时,当有回复时,会收到邮件提醒( 注:邮件提醒功能还在制作中 ).


回应区🔗

你有对这篇文章写回应吗? 你可以在这里提交你的文章网址或者推特链接(文章或推特内容需要包含这篇文章的地址,点击这里了解 Webmention):

回应内容会被 webmention.io 机器人收集,另一位机器人会在24小时内把回应展示到这里, 也欢迎通过 邮件 Twitter DM 和我讨论。

Back to top