7、隧道工具
7.1、openvpn
OpenVPN 官方地址:https://github.com/OpenVPN/openvpn
OpenVPN 的功能很强大,我们并没有深入研究该工具,按照以下步骤配置,基本上够用。
7.1.2、环境准备
软硬件版本
硬件 | 操作系统 | 软件 |
---|---|---|
ARM64 ft2000+ | centos7.5 | easy-rsa3.0.6 openvpn2.4.7 |
软件安装源
# cat /etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-$releasever - Base
baseurl=https://mirrors.aliyun.com/centos-altarch/$releasever/os/$basearch/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#released updates
[updates]
name=CentOS-$releasever - Updates
baseurl=https://mirrors.aliyun.com/centos-altarch/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
baseurl=https://mirrors.aliyun.com/centos-altarch/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
enabled=1
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
baseurl=https://mirrors.aliyun.com/centos-altarch/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
# cat /etc/yum.repos.d/epel.repo
[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch
metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
安装软件包
# yum install easy-rsa openvpn -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* epel: mirrors.yun-idc.com
Package easy-rsa-3.0.6-1.el7.noarch already installed and latest version
Package openvpn-2.4.7-1.el7.aarch64 already installed and latest version
Nothing to do
7.1.3、配置 easy-rsa 3.0.6
安装完 easy-rsa 3.0.6 后,默认会生成 easyrsa 脚本文件和 vars.example 环境变量文件,这两个文件是核心文件,找到这两个文件所在的目录,复制到相应的位置,然后根据自己的需求配置 vars
# find /usr/ -name easyrsa -o -name vars.example
/usr/share/doc/easy-rsa-3.0.6/vars.example
/usr/share/easy-rsa/3.0.6/easyrsa
# cp -r /usr/share/easy-rsa/3.0.6/ /etc/openvpn/3.0.6/
# cp /usr/share/doc/easy-rsa-3.0.6/vars.example /etc/openvpn/3.0.6/vars
# grep -v "^#\|^$" /etc/openvpn/3.0.6/vars
if [ -z "$EASYRSA_CALLER" ]; then
echo "You appear to be sourcing an Easy-RSA 'vars' file." >&2
echo "This is no longer necessary and is disallowed. See the section called" >&2
echo "'How to use this file' near the top comments for more details." >&2
return 1
fi
set_var EASYRSA_REQ_COUNTRY "CN"
set_var EASYRSA_REQ_PROVINCE "HuNan"
set_var EASYRSA_REQ_CITY "ChangSha"
set_var EASYRSA_REQ_ORG "Greatwall Corporation"
set_var EASYRSA_REQ_EMAIL "yuliangliang@greatwall.com.cn"
set_var EASYRSA_REQ_OU "Product Department"
[root@openvpn ~]#
7.1.3.1、easyrsa 命令使用
查看整体帮助
# ./easyrsa -h
查看某个子命令的详细帮助
# ./easyrsa help import-req
查看可以用到的 options
# ./easyrsa help options
7.1.3.2、创建 PKI 和 CA
# cd /etc/openvpn/3.0.6/
# ./easyrsa init-pki
# ls
easyrsa openssl-easyrsa.cnf pki vars x509-types
# ./easyrsa build-ca nopass (配置好了vars直接回车即可)
执行 ./easyrsa init-pki
后,EasyRSA
会在当前目录下创建一个名为 pki
的目录结构,包含以下内容:
pki/private
:用于存放私钥文件,权限严格受限,确保密钥的安全。pki/reqs
:用于存放证书签名请求(CSR)。pki/issued
:用于存放签名后的证书(例如.crt
文件)。pki/certs_by_serial
:存放按序列号命名的已签发证书(通常只在调试或跟踪中使用)。pki/index.txt
:一个索引文件,用于跟踪签发的所有证书。pki/serial
:一个文件,用于记录下一个将要分配的证书序列号。
命令 ./easyrsa build-ca nopass
是使用 EasyRSA
工具创建一个证书颁发机构(CA, Certificate Authority)的根证书和私钥。它是建立 PKI(公钥基础设施)中最重要的一步。
build-ca
:子命令,表示创建一个证书颁发机构(CA)。
- 该命令会生成 CA 的私钥和根证书。
- CA 的主要作用是签署证书签名请求(CSR),生成可信任的服务器或客户端证书。
- 根证书是所有后续签名的基础。
nopass
:选项,表示生成的 CA 私钥不设置密码保护。
- 如果没有
nopass
,生成的私钥需要设置一个密码,每次使用时需要输入密码。
运行命令后,会在 pki
目录中生成以下文件:
pki/private/ca.key
:CA 的私钥文件,用于签署证书。必须妥善保管,泄露会导致整个 PKI 系统的安全性失效。pki/ca.crt
:CA 的根证书,用于验证由 CA 签发的所有证书。这个文件通常会分发给客户端或服务器,用于信任链的验证。
7.1.3.3、创建服务端证书
# ./easyrsa gen-req server nopass (回车即可)
./easyrsa
:这是 EasyRSA
工具的可执行脚本,用于管理私钥、证书、证书请求等。
gen-req
:这个子命令用于生成证书签名请求(CSR)。它会同时生成一个私钥文件和一个与之关联的证书签名请求文件。
server
:这是证书签名请求的名称(common name, CN)。生成的文件会以这个名字命名,比如:
- 私钥:
server.key
- CSR 文件:
server.req
nopass
:这个选项表示生成的私钥文件不需要设置密码保护。如果没有 nopass
,生成的私钥文件会要求输入密码才能使用。
7.1.3.4、签约服务端证书
[root@openvpn 3.0.6]# ./easyrsa sign server server
sign
:EasyRSA
子命令,表示对证书签名请求(CSR)进行签名。
server
:表示证书的类型。
server
类型的证书通常用于服务器(如 OpenVPN 服务器)。- EasyRSA 会根据配置为服务器证书添加相关扩展字段(如
extendedKeyUsage = serverAuth
)。
server
:第二个 server
是证书签名请求(CSR)的名称,与之前通过 gen-req
生成时的名称一致。
- 它表示要签名的 CSR 文件,通常是
pki/reqs/server.req
。 - 签名后的证书会被命名为
server.crt
,并保存在pki/issued/
目录下。
7.1.3.5、创建 Diffie-Hellman
# ./easyrsa gen-dh
Diffie-Hellman (DH) 是一种密钥交换协议,用于安全生成共享密钥。
- 在 SSL/TLS 通信中,它用于支持 Perfect Forward Secrecy (PFS),即使私钥泄露,之前的通信数据仍然无法解密。
- 在 OpenVPN 服务器配置中,DH 参数文件是服务器端密钥交换的一部分,确保客户端与服务器之间的通信加密。
7.1.3.6、客户端证书请求
# ./easyrsa gen-req jiajia nopass
7.1.3.7、签约客户端证书
# ./easyrsa sign client jiajia
注意:这里的客户端证书用到的 pki 目录跟服务器端的 pki 目录是一样的,所以可以直接 sign 签署,如果客户端重新生成了 pki,那每次生成的证书请求文件都需要用 ./easyrsa import-req $PATH/jiajia.req jiajia
导入并取一个短名字 jiajia,然后执行 ./easyrsa sign client jiajia
;
参见 ./easy-rsa help import-req
7.1.3.8、生成 ta.key 文件
[root@openvpn 3.0.6]# openvpn --genkey --secret ta.key
命令 openvpn --genkey --secret ta.key
是用于生成一个预共享密钥(TA 密钥,TLS Authentication Key)。这在 OpenVPN 中主要用于增强安全性,防止未经授权的连接尝试和某些类型的攻击(如 DoS 攻击)。
--genkey
:生成密钥的选项。
--secret ta.key
:指定生成的密钥文件名为 ta.key
。
- 这个密钥是一个对称密钥,客户端和服务器共享。
- 文件内容是一个随机生成的 2048 位密钥。
TLS Authentication:TA 密钥用于 OpenVPN 的 TLS 认证模式。在 TLS 握手过程中,只有提供正确的 TA 密钥的客户端才会被服务器接受。
- 防止未经授权的连接尝试。
- 增加防火墙规则配置的灵活性。
防御攻击:TA 密钥能有效阻止某些类型的攻击。
- 防止 DoS 攻击:通过过滤非授权数据包减轻负载。
- 防止中间人攻击:确保握手数据的完整性。
7.1.3.9、整理证书
# pwd
/etc/openvpn/3.0.6
# ll pki/private/
-rw-------. 1 root root 1679 Jun 9 21:05 ca.key
-rw-------. 1 root root 1708 Jun 9 21:06 server.key
# ll pki/issued/
-rw-------. 1 root root 4552 Jun 9 21:18 server.crt
# ll pki/ca.crt
-rw-------. 1 root root 1172 Jun 9 21:05 pki/ca.crt
# ll pki/dh.pem
-rw-------. 1 root root 424 Jun 9 21:10 pki/dh.pem
# cp ta.key pki/
# ll pki/ta.key
-rw-------. 1 root root 636 Jun 9 21:31 pki/ta.key
以上配置文件将会在服务器端和端户端配置文件中指出。
7.1.4、服务器端配置文件
# grep -vE "^#|^$" /etc/openvpn/server.conf
local 172.18.1.206
port 1194
proto tcp
dev tun
ca /etc/openvpn/3.0.6/pki/ca.crt
cert /etc/openvpn/3.0.6/pki/issued/server.crt
key /etc/openvpn/3.0.6/pki/private/server.key
dh /etc/openvpn/3.0.6/pki/dh.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 172.17.0.0 255.255.0.0"
keepalive 10 120
tls-auth /etc/openvpn/3.0.6/pki/ta.key 0
cipher AES-256-CBC
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 3
reneg-sec 0
# 注意,这个文件用来记录被吊销的证书,阻止被吊销的客户再次登陆
# 默认没有这个文件,必须执行 ./easyrsa gen-crl 更新生成,否则服务启不来
crl-verify /etc/openvpn/3.0.6/pki/crl.pem
7.1.5、启动 openvpn 服务
# systemctl start openvpn@server.service
# systemctl enable openvpn@server.service
7.1.6、配置 iptables 规则
为了可以让客户端访问服务器所在局域网的其它主机,需要配置如下规则
# iptables -t nat -A POSTROUTING -s 10.8.0.0/8 -j MASQUERADE
# echo "1" > /proc/sys/net/ipv4/ip_forward
# cat /proc/sys/net/ipv4/ip_forward
1
7.1.7、客户端的配置文件
client
dev tun
proto tcp
remote 36.158.226.1 16001
resolv-retry infinite
persist-key
persist-tun
mute-replay-warnings
ca ca.crt
cert yll.crt
key yll.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
comp-lzo
verb 3
mute 20
reneg-sec 0
7.1.8、生成客户端证书脚本
#!/bin/bash
install_expect() {
if ! rpm -q expect &>/dev/null; then
yum install expect -y
if ! [ $? -eq 0 ]; then
echo "Error: you must install expect manually!"
exit -1
fi
fi
}
validate_input() {
if [ $# -ne 1 ]; then
echo "Usage: $0 USER_NAME"
echo "-1"
exit -1
fi
if ! [[ $1 =~ ^[a-zA-Z0-9_]{3,16}$ ]]; then
echo "请使用字母数字或下划线开头的3到16个字符的名字"
echo "-1"
exit -1
fi
}
check_existing_user() {
local username=$1
cd $dir
if ./easyrsa show-cert "$username" &>/dev/null; then
echo "此用户已存在,请重新输入"
echo "-1"
exit -1
fi
}
generate_cert_request() {
local username=$1
expect <<-EOF
spawn ./easyrsa gen-req $username nopass
expect {
"$username" { send "\n" }
}
expect eof
EOF
}
sign_cert_request() {
local username=$1
./easyrsa import-req "$dir/pki/reqs/${username}.req" "$username"
expect <<-EOF
spawn ./easyrsa sign client $username
expect {
"Confirm" { send "yes\n" }
}
expect eof
EOF
}
prepare_client_cert_directory() {
local username=$1
if [ -d "/client.certs/$username" ]; then
rm -rf "/client.certs/$username"
fi
mkdir -p "/client.certs/$username"
}
create_client_ovpn_template() {
cat > /client.certs/clientsample.ovpn <<-EOF
client
dev tun
proto tcp
remote 61.187.64.38 11940
resolv-retry infinite
persist-key
persist-tun
mute-replay-warnings
ca ca.crt
cert sample.crt
key sample.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
comp-lzo
verb 3
mute 20
reneg-sec 0
EOF
}
finalize_client_ovpn() {
local username=$1
cd /client.certs
cp clientsample.ovpn client.ovpn
sed -i "s@sample.crt@${username}.crt@g" client.ovpn
sed -i "s@sample.key@${username}.key@g" client.ovpn
mv client.ovpn "$username/"
}
copy_cert_files() {
local username=$1
cp "$dir/pki/ca.crt" "/client.certs/$username"
cp "$dir/pki/ta.key" "/client.certs/$username"
cp "$dir/pki/issued/${username}.crt" "/client.certs/$username"
cp "$dir/pki/private/${username}.key" "/client.certs/$username"
}
# Main script execution
install_expect
dir=/etc/openvpn/3.0.6
validate_input "$@"
check_existing_user "$1"
generate_cert_request "$1"
sign_cert_request "$1"
if ! [ -d /client.certs/ ]; then
mkdir /client.certs/
fi
create_client_ovpn_template
prepare_client_cert_directory "$1"
copy_cert_files "$1"
finalize_client_ovpn "$1"
echo "用户 $1 的 OpenVPN 证书已生成!"
7.1.9、吊销客户端证书脚本
#!/bin/bash
validate_input() {
if [ $# -ne 1 ]; then
echo "Usage: $0 USER_NAME"
echo "-1"
exit -1
fi
if ! [[ $1 =~ ^[a-zA-Z0-9_]{3,16}$ ]]; then
echo "请使用字母数字或下划线开头的3到16个字符的名字"
echo "-1"
exit -1
fi
}
check_user_existence() {
local username=$1
cd $dir
if ! ./easyrsa show-cert "$username" &>/dev/null; then
echo "没有这个用户,无法删除"
echo "-1"
exit -1
fi
}
revoke_certificate() {
local username=$1
expect <<-EOF
spawn ./easyrsa revoke $username
expect {
"revocation" { send "yes\n" }
}
expect eof
EOF
./easyrsa gen-crl
}
delete_user_directory() {
local username=$1
rm -rf "/client.certs/$username"
}
# Main script execution
dir=/etc/openvpn/3.0.6
validate_input "$@"
check_user_existence "$1"
revoke_certificate "$1"
delete_user_directory "$1"
echo "用户 $1 的证书已被成功吊销并删除。"
7.2、openssh
7.2.1、本地端口转发
场景:我们需要远程使用 telnet 协议连接到某个被防火墙保护的内部网络中去。
SSH 的本地端口转发的格式如下:
ssh -L local_port:remote_host:remote_host_port sshserver
本地端口转发有如下常用选项:
-f
:将 SSH 客户端放到后台运行,保持连接但不阻塞终端。-N
:只建立端口转发,而不打开远程 shell 或执行命令。单独使用-N
会阻塞终端(除非与-f
一起使用)。-g
:启用网关功能,允许非本地主机通过 SSH 客户端的本地端口发起连接,
我们的实现如下所示。 这个过程是在外部主机(172.18.253.127)上进行操作:
ssh -L 9527:172.18.253.58:23 -Nf 172.18.250.114
通过本地监听端口,使用 telnet 协议就可以访问到内部的数据库服务器了:
telnet 127.0.0.1 9527
7.2.2、远程端口转发
场景:外部主机不能访问内部主机,但内部主机可以访问外部主机,实现外部主机访问内部数据库。
SSH 远程端口转发的格式如下:
ssh -R sshserver_port:remote_host:remotehost_port sshserver
我们的实现如下所示。 这个过程是在内部主机(172.18.250.114)上进行的操作:
ssh -R 9527:172.18.253.58:25 -Nf 172.18.253.127
此时我们切换到外部主机(172.18.253.127),使用 ss -tnlpu 查看一下当前监听的端口,就会发现开启了 9527 端口。如果此时我们使用 telnet 命令连接一下本地的端口,就能够像 SMTP 服务器发起 SMTP 请求了。
telnet 127.0.0.1 9527
7.2.3、动态端口转发
场景:我们在防火墙内部想要访问放火墙外面的网站,但是防火墙给我们开放了很少的端口。如何不受限制访问外面。
SSH 动态端口转发的格式如下:
# ssh server 指的就是我们在放火墙之外的代理服务器
# 1080 也可以是其他可用端口
ssh -D 1080 root@sshserver
我们为墙内的主机设置一下动态代理,执行这条命令的是172.18.253.127
ssh -D 1080 root@172.18.250.114
这时通过动态转发,可以将墙内主机发起的请求,转发到墙外主机,而由墙外主机去真正地发起请求。而在墙内发起的请求,需要由 Socket 代理(Socket Proxy)转发到 SSH 绑定的 1080 端口。我们以火狐浏览器为例,配置本地的网络访问代理。找到设置 => 高级 => 网络 => 代理,然后设置成如下的内容。
这样的话,Firefox 浏览器发起的请求都会转发到 1080 端口,然后通过 SSH 转发到真正的请求地址。
7.2.4、ssh 基于密钥登陆
ssh 连接大家经常用,也很好用,没有太在意,后来用到 CentOS8,openEuler24.03,KylinV10 时经常出问题,基于密钥无法认证。这里梳理一下 ssh 的认证,以及该注意的事项。
SSH 连接的主要流程:
- 连接建立与协商(握手阶段)
服务器与客户端通过非对称密钥协商生成对称密钥,并商定加密、认证算法。 - 用户认证(认证阶段)
客户端用非对称密钥或密码进行认证,服务器验证合法性。 - 数据传输(传输阶段)
双方使用协商好的对称密钥加密数据,同时通过消息认证码(MAC)校验数据完整性。
1、握手阶段
Protocol 2
仅支持 SSH 协议版本 2(v2)。
-
SSH v1 存在严重漏洞(例如明文密钥交换)。
-
SSH v2 支持强加密(如 Diffie-Hellman、ECC)。
-
握手阶段,双方协商协议版本。如果客户端试图使用 v1,会被拒绝连接。
-
此配置决定了后续密钥交换算法 (
KexAlgorithms
)、加密算法 (Ciphers
)、认证方式 (PubkeyAuthentication
) 是否适用。
KexAlgorithms curve25519-sha256, diffie-hellman-group-exchange-sha256
指定密钥交换算法,生成对称密钥。
-
curve25519-sha256
:使用椭圆曲线 Diffie-Hellman(ECDH)交换密钥,速度快且安全性高。 -
diffie-hellman-group-exchange-sha256
:传统 Diffie-Hellman,但使用 SHA-256 防止弱散列攻击。 -
握手阶段,双方协商使用的密钥交换算法。
-
客户端提议
curve25519-sha256
,服务器接受,双方利用此算法生成对称密钥 K。 -
密钥交换算法直接影响后续的加密算法 (Ciphers) 和认证过程。
- 对称加密密钥:密钥交换后,生成的对称密钥将用于数据加密。
- 安全性影响:如果使用弱密钥交换算法(如
diffie-hellman-group1-sha1
),可能被中间人攻击。
Ciphers aes128-ctr,aes256-gcm@openssh.com
- 指定用于数据加密的对称算法,算法中是用对称密钥 K 去加密数据。
- 依赖密钥交换算法 (
KexAlgorithms
) 提供的对称密钥 K。 - 与完整性保护参数 (
MACs
) 协同防止数据篡改。
- 依赖密钥交换算法 (
MACs hmac-sha2-256,hmac-sha2-512
指定消息认证码(MAC)算法,用于校验数据完整性。
-
hmac-sha2-256
:SHA-256 HMAC 算法,验证数据是否被篡改。 -
hmac-sha2-512
:更强的完整性保护。 -
每个加密的数据包都附带 MAC 值,接收方根据密钥重新计算并对比,确认数据完整性。
- 与
Ciphers
配合使用,加密后的数据需附加 MAC。 - 如果选择
aes256-gcm
,其 GCM 模式内置完整性保护,MACs
参数可能被忽略。
- 与
2、用户认证阶段
PubkeyAuthentication yes
启用基于非对称密钥的公钥认证。
- 客户端用私钥签名,服务器用对应公钥验证签名。
- 客户端发送公钥到服务器。
- 服务器验证公钥是否在
~/.ssh/authorized_keys
中。 - 服务器发送随机数据,要求客户端用私钥签名。
- 服务器用公钥验证签名,确认用户身份。
- 配合
PubkeyAcceptedKeyTypes
限制可用密钥类型(如ssh-ed25519
)。 - 强烈建议禁用密码认证(
PasswordAuthentication no
),仅使用公钥认证。
PubkeyAcceptedKeyTypes ssh-ed25519,rsa-sha2-256
- 指定允许的公钥类型。
ssh-ed25519
:基于椭圆曲线 Ed25519 的公钥算法,速度快,安全性高。rsa-sha2-256
:RSA 公钥算法,使用 SHA-256 散列。
- 服务器检查客户端提交的公钥类型是否符合配置,若不支持客户端的公钥类型,认证会失败。
StrictModes yes
- 启用严格权限检查,防止权限过宽导致安全漏洞。
- 用户登录前,服务器检查以下文件的权限:
~/.ssh
必须为 700。~/.ssh/authorized_keys
必须为 600。
IgnoreRhosts yes
- 禁用基于
~/.rhosts
和/etc/hosts.equiv
文件的认证方式。 - 需要配合
HostbasedAuthentication no
使用,因为HostbasedAuthentication
依赖于rhosts
。
HostbasedAuthentication no
- 禁用主机认证(Host-based Authentication)。这种认证方式允许通过主机的私钥来认证用户,但需要客户端和服务器有匹配的主机密钥和可信设置。
- 与
IgnoreRhosts yes
联动。如果HostbasedAuthentication
被禁用,~/.rhosts
和/etc/hosts.equiv
文件就没有作用。 - 使用更安全的
PubkeyAuthentication
替代。
HostbasedAcceptedKeytypes
- 定义允许用于主机认证(Host-based Authentication)的公钥算法。
- 默认值通常包括较安全的算法,如
ssh-ed25519
和rsa-sha2-512
。 - 认证阶段如果启用了
HostbasedAuthentication
,服务器会验证这些算法生成的签名。 - 如果
HostbasedAuthentication no
,此参数将被忽略。
PermitUserEnvironment no
-
禁止通过
.ssh/environment
文件设置环境变量。 -
防止攻击者利用恶意环境变量干扰会话行为。
-
登录阶段如果启用了用户环境配置,服务器会读取
~/.ssh/environment
文件并应用其中的变量。
AllowTcpForwarding no
- 禁止 SSH 会话中的 TCP 转发功能。
- 这意味着客户端不能通过服务器建立额外的 TCP 通道。
- 会话阶段防止用户在已登录的会话中转发流量到其他目标主机。
- 可配合
AllowAgentForwarding no
使用,彻底防止用户滥用会话隧道功能。
AllowAgentForwarding no
- 禁止客户端通过 SSH 代理转发认证请求。
GatewayPorts no
- 禁止远程端口转发对外开放端口。
- 即便开启了端口转发,转发的端口只能监听
localhost
,不能对外提供服务。 - 配合
AllowTcpForwarding no
可完全关闭所有转发功能。
PermitTunnel no
- 禁止通过 SSH 创建网络隧道(Layer 2 或 Layer 3)。
- 防止用户利用隧道访问内部网络资源。
- 同样是限制 SSH 会话能力的参数,配合
AllowTcpForwarding no
提高安全性。
GSSAPIKexAlgorithms
-
定义支持的 GSSAPI 密钥交换算法。
-
用于 Kerberos 或其他基于 GSSAPI 的认证协议。
-
密钥交换阶段,当客户端和服务器都支持 GSSAPI 时,可以协商使用这些算法进行密钥交换。
-
如果服务器启用了
GSSAPIAuthentication yes
,会使用此参数指定支持的 GSSAPI 算法。 -
常见于需要 Kerberos 集成的环境。
CASignatureAlgorithms
- 定义允许使用的 CA 签名算法。
- SSH 可以通过 CA 签名的公钥进行认证,此参数限制支持的 CA 签名类型。
- 认证阶段,验证客户端或服务器的公钥是否被允许的 CA 签名。
- 与
PubkeyAcceptedKeyTypes
和HostKeyAlgorithms
结合,用于限制公钥的类型和 CA 签名。
HostKeyAlgorithms
- 定义服务器支持的主机密钥算法。
- 主机密钥用于验证服务器的身份。
- 认证阶段,客户端验证服务器提供的主机密钥是否匹配信任列表。
- 与
PubkeyAcceptedKeyTypes
相辅相成,分别限制客户端和服务器的密钥类型。 - 建议仅使用现代算法(如
ssh-ed25519
和rsa-sha2-512
)。
3、数据传输阶段
ClientAliveCountMax 0
和 ClientAliveInterval
控制客户端的空闲连接行为。
ClientAliveInterval
:服务器向客户端发送心跳包的间隔(秒)。ClientAliveCountMax
:客户端未响应心跳包后允许的最大次数。- 每隔
ClientAliveInterval
秒,服务器发送心跳包。如果客户端无响应,断开连接。 - 设置为
0
表示立即断开连接。
- 每隔
注意:如果基于密钥认证出现所选的用户密钥未在远程主机上注册,一般是目录和文件权限问题,或者是两边算法不匹配,那就好好理解上面的参数含义。
7.3、frp
官方仓库:https://github.com/fatedier/frp
官方文档:https://gofrp.org/zh-cn/docs/
frp 是什么?
frp 是一款高性能的反向代理应用,专注于内网穿透。它支持多种协议,包括 TCP、UDP、HTTP、HTTPS 等,并且具备 P2P 通信功能。使用 frp,您可以安全、便捷地将内网服务暴露到公网,通过拥有公网 IP 的节点进行中转。
为什么选择 frp?
通过在具有公网 IP 的节点上部署 frp 服务端,您可以轻松地将内网服务穿透到公网,并享受以下专业特性:
- 多种协议支持:客户端服务端通信支持 TCP、QUIC、KCP 和 Websocket 等多种协议。
- TCP 连接流式复用:在单个连接上承载多个请求,减少连接建立时间,降低请求延迟。
- 代理组间的负载均衡。
- 端口复用:多个服务可以通过同一个服务端端口暴露。
- P2P 通信:流量不必经过服务器中转,充分利用带宽资源。
- 客户端插件:提供多个原生支持的客户端插件,如静态文件查看、HTTPS/HTTP 协议转换、HTTP、SOCKS5 代理等,以便满足各种需求。
- 服务端插件系统:高度可扩展的服务端插件系统,便于根据自身需求进行功能扩展。
- 用户友好的 UI 页面:提供服务端和客户端的用户界面,使配置和监控变得更加方便。
官方示例够用了 https://gofrp.org/zh-cn/docs/examples/
通过简单配置 TCP 类型的代理,使用户能够访问内网服务器。
步骤
-
在具有公网 IP 的机器上部署 frps
部署 frps 并编辑 frps.toml 文件。以下是简化的配置,其中设置了 frp 服务器用于接收客户端连接的端口:
bindPort = 7000
-
在需要被访问的内网机器上部署 frpc
部署 frpc 并编辑 frpc.toml 文件,假设 frps 所在服务器的公网 IP 地址为 x.x.x.x。以下是示例配置:
serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" localPort = 22 remotePort = 6000
localIP
和localPort
配置为需要从公网访问的内网服务的地址和端口。remotePort
表示在 frp 服务端监听的端口,访问此端口的流量将被转发到本地服务的相应端口。- 注意,仅启动 frps 服务端是没有
remotePort
端口监听的,只有 frpc 客户端启动,连接 frps 服务端时,remotePort
端口才会送到服务端,服务端开始监听该端口。
- 注意,仅启动 frps 服务端是没有
-
启动 frps 和 frpc
-
通过 SSH 访问内网机器
使用以下命令通过 SSH 访问内网机器,假设用户名为 test:
ssh -o Port=6000 test@x.x.x.x
frp 将请求发送到
x.x.x.x:6000
的流量转发到内网机器的 22 端口。
官方仓库有完整的配置参考 https://github.com/fatedier/frp/tree/dev/conf ,当然官方文档也有详细说明,一般从完整配置中取一部分也就够用了。