Centos

OpenVPN 與 PAM 與 systemd 和 SELinux

  • July 28, 2020

我正在嘗試在 CentOS 8.2 上使用 PAM 登錄設置 OpenVPN (2.4.9) 伺服器,但我遇到了一些奇怪的問題。具體來說,如果我使用 systemd 單元文件中指定的 ExecStart 命令啟動伺服器,我可以成功驗證

sudo /usr/sbin/openvpn --status /home/XXX/openvpn.log --status-version 2 --suppress-timestamps --cipher AES-256-GCM --ncp-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC:AES-128-CBC:BF-CBC --config server.conf

但是,如果我通過 systemd 啟動伺服器

sudo systemctl start openvpn-server@server

我在我的 openvpn 日誌中看到以下身份驗證錯誤

AUTH-PAM: BACKGROUND: received command code: 0
AUTH-PAM: BACKGROUND: USER: XXXX
AUTH-PAM: BACKGROUND: my_conv[0] query='Password: ' style=1
AUTH-PAM: BACKGROUND: user 'XXXX' failed to authenticate: Authentication failure
2.204.43.58:49048 PLUGIN_CALL: POST /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so/PLUGIN_AUTH_USER_PASS_VERIFY status=1
2.204.43.58:49048 PLUGIN_CALL: plugin function PLUGIN_AUTH_USER_PASS_VERIFY failed with status 1: /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so
2.204.43.58:49048 TLS Auth Error: Auth Username/Password verification failed for peer

有沒有人知道問題可能是什麼?我一定對額外的 systemd 配置有所了解,還是我錯了?

乾杯!

託拜厄斯

systemd-unit 文件/lib/systemd/system/openvpn-server@.service如下所示:

[Unit]
Description=OpenVPN service for %I
After=syslog.target network-online.target
Wants=network-online.target
Documentation=man:openvpn(8)
Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
Documentation=https://community.openvpn.net/openvpn/wiki/HOWTO

[Service]
Type=notify
PrivateTmp=true
WorkingDirectory=/etc/openvpn/server
ExecStart=/usr/sbin/openvpn --status %t/openvpn-server/status-%i.log --status-version 2 --suppress-timestamps --cipher AES-256-GCM --ncp-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC:AES-128-CBC:BF-CBC --config %i.conf
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE CAP_AUDIT_WRITE
LimitNPROC=10
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw
ProtectSystem=true
ProtectHome=true
KillMode=process
RestartSec=5s
Restart=on-failure

[Install]
WantedBy=multi-user.target

這是我的 openvpn server.conf

port 1194
proto udp
dev tun
ca /etc/openvpn/server/easy-rsa/3/pki/ca.crt
cert /etc/openvpn/server/easy-rsa/3/pki/issued/server.crt
key /etc/openvpn/server/easy-rsa/3/pki/private/server.key
dh /etc/openvpn/server/easy-rsa/3/pki/dh.pem
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
duplicate-cn
keepalive 10 120
cipher AES-128-GCM
comp-lzo
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
verb 6
plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn
username-as-common-name

這裡是我的 openvpn Pam 文件

auth required pam_succeed_if.so user ingroup vpnlogin
auth substack system-auth
auth include postlogin
account required pam_nologin.so
account include system-auth
password include system-auth
session required pam_selinux.so close
session required pam_loginuid.so
session optional pam_console.so
session required pam_selinux.so open
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include system-auth
session include postlogin
-session optional pam_ck_connector.so

/var/log/secure 中的身份驗證日誌如下所示:

Jul 15 17:23:51 YYYY openvpn[9730]: pam_succeed_if(openvpn2:auth): requirement "user ingroup vpnlogin" was met by user "XXXX"
Jul 15 17:23:51 YYYY unix_chkpwd[9747]: check pass; user unknown
Jul 15 17:23:51 YYYY unix_chkpwd[9748]: check pass; user unknown
Jul 15 17:23:51 YYYY unix_chkpwd[9748]: password check failed for user (XXXX)
Jul 15 17:23:51 YYYY openvpn[9730]: pam_unix(openvpn2:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=  user=XXXX

/var/log/audit/audit.log 中的審計日誌如下所示:

type=SERVICE_START msg=audit(1594833821.311:12583): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=openvpn-server@server comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'^]UID="root" AUID="unset"
type=SERVICE_START msg=audit(1594833821.395:12584): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=NetworkManager dispatcher comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'^]UID="root" AUID="unset" 
type=AVC msg=audit(1594833831.005:12585): avc:  denied  { dac_override } for  pid=9747 comm="unix_chkpwd" capability=1  scontext=system_u:system_r:chkpwd_t:s0 tcontext=system_u:system_r:chkpwd_t:s0 tclass=capability permissive=0
type=AVC msg=audit(1594833831.007:12586): avc:  denied  { dac_override } for  pid=9748 comm="unix_chkpwd" capability=1  scontext=system_u:system_r:chkpwd_t:s0 tcontext=system_u:system_r:chkpwd_t:s0 tclass=capability permissive=0
type=USER_AUTH msg=audit(1594833831.008:12587): pid=9730 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:openvpn_t:s0 msg='op=PAM:authentication grantors=? acct="XXXX" exe="/usr/sbin/openvpn" hostname=? addr=? terminal=? res=failed'^]UID="root" AUID="unset"
type=SERVICE_STOP msg=audit(1594833831.255:12588): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=NetworkManager dispatcher comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'^]UID="root" AUID="unset"

解析度

我不知道這是否是最好的解決方案,但是當我替換CAP_DAC_OVERRIDECAP_DAC_READ_SEARCH. 我的理解是,從安全的角度來看,無論如何這可能更可取。CapabilityBoundingSet``/lib/systemd/system/openvpn-server@.service

警告:雖然對於我的配置,這並沒有引發任何問題,而且一切似乎執行順利,但它可能會給其他配置帶來問題,因為 openvpn 單元以較少的權限執行。

可能會發生什麼

我假設它unix_chkpwd是使用呼叫程序的功能執行的,這將是CAP_DAC_OVERRIDE. 但是,由於unix_chkpwd不需要此訪問級別,它會被 SELinux 拒絕並且無法打開/etc/shadow. 如果有人對 systemd/pam/SELinux 有更深入的了解,我會很高興得到糾正。

引用自:https://serverfault.com/questions/1025357