最後更新: 2019-07-15
介紹
SOCKS performs at Layer 5 of the OSI model (the session layer)
Default Port: 1080/tcp
SOCKS Protocol Version 5 (RFC 1928)
- Username/Password Authentication for SOCKS V5 (RFC 1929)
- Support UDP (which can be used for DNS lookups)
Compile & Install
Prepare
yum install pam-devel tcp_wrappers-devel
Comfigure
./configure --prefix=/opt/dante \ --sysconfdir=/etc \ --disable-client \ --without-bsdauth \ --without-gssapi \ --without-krb5 \ --without-upnp
Compile
cd /usr/src
wget https://www.inet.no/dante/files/dante-1.4.2.tar.gz
tar -zxf dante-1.4.2.tar.gz
cd dante-1.4.2
make; make install
cp example/sockd.conf /etc
Checking
# Version
/opt/dante/sbin/sockd -v
Dante v1.4.2. Copyright (c) 1997 - 2014 Inferno Nettverk A/S, Norway
# Verifies config file and exits
/opt/dante/sbin/sockd -V
Setting
useradd -r -s /bin/false sockd
/etc/security/limits.conf
sockd - nofiles 65535
firewall-cmd --add-port=10080/tcp
firewall-cmd --add-port=10080/tcp --permanent
Remark: test it without login
firewall-cmd --add-rich-rule='rule family="ipv4" source address="w.x.y.z" port protocol="tcp" port="10080" accept'
Daemon
-D Dante will detach from the controlling terminal and run in the background as a system daemon.
-p <filename> : write pid to <filename> [/var/run/sockd.pid]
In / Out Interface
The server receives SOCKS requests from SOCKS clients on the internal address,
and uses the external interface when forwarding data from the SOCKS clients to the external network.
external: eth1 # internal: 192.0.2.1 port = 1080 internal: eth1 port = 1080
Log Setting
# syslog, stdin, stdout, file
設定有 log 時 log 到那檔案, default 係沒有 logging 的 (unless debugging has been enabled)
logoutput: /var/log/sockd.log # only error-related logoutput # not include client-specific errors, but only more serious "global" errors. errorlog: /var/log/sockd.errlog
# debug: 0 - No debug logging
# debug: 1 - Some debug logging
# debug: 2 - Verbose debug logging
debug: 1
log 可以在 client / socks rule 內設定
client pass {
from: s.s.s.s/32 to: 0.0.0.0/0
log: error # connect, disconnect
}
logs:
- error
- connect - Information about accepted client connections.
- disconnect - Information about disconnecting clients.
- ioop - Logging of each data transfer operation.
- data - Logging of the actual data transferred.
- tcpinfo - Logging of information obtained via the TCP_INFO socket option
Status information
Upon reception of a SIGUSR1 signal,
the Dante server will write various types of status information to the files specified by the logoutput keyword.
kill -s SIGUSR1 1093
... sockd[1093]: info: Dante v1.4.2 up 1 day, 19:16, a: 7, h: 7 c: 0 ... sockd[1093]: info: negotiators (1): a: 7, h: 3, c: 0, f: 96 ... sockd[1093]: info: requesters (16): a: 3, h: 3, c: 0, f: 16 ... sockd[1093]: info: iorelayers (1): a: 3, h: 3, c: 0, f: 32 ... sockd[1093]: info: max limits: processes: 3833 (3814 free), files: 4096 (4043 free), negotiate-child-slots: 194016, request-child-slots: 2021, io-child-slots: 64672 (max clients limited by open file limit) ... sockd[1094]: info: monitor-child up 1 day, 19:16:46 ... sockd[1102]: info: request-child up 1 day, 19:16:46 ... sockd[1105]: info: request-child up 1 day, 19:16:46 ... sockd[1103]: info: request-child up 1 day, 19:16:46 ... sockd[1107]: info: request-child up 1 day, 19:16:46 ... sockd[1109]: info: request-child up 1 day, 19:16:46 ... sockd[1106]: info: request-child up 1 day, 19:16:46 ... sockd[1114]: info: request-child up 1 day, 19:16:37 ... sockd[1110]: info: request-child up 1 day, 19:16:46 ... sockd[1101]: info: request-child up 1 day, 19:16:46 ... sockd[1099]: info: request-child up 1 day, 19:16:46 ... sockd[2401]: info: request-child up 0 days, 0:04:12 ... sockd[1100]: info: request-child up 1 day, 19:16:46 ... sockd[1111]: info: request-child up 1 day, 19:16:46 ... sockd[1104]: info: request-child up 1 day, 19:16:46 ... sockd[2402]: info: io-child up 0 days, 0:04:12 ... sockd[2402]: info: no read-only latency information available (yet) ... sockd[2402]: info: no i/o latency information available (yet) ... sockd[1108]: info: request-child up 1 day, 19:16:46 ... sockd[2403]: info: negotiate-child up 0 days, 0:02:05 ... sockd[1098]: info: request-child up 1 day, 19:16:46
Privileged
the user.privileged keyword is generally only required to use some of the authentication methods,
or if the server needs to bind privileged TCP/UDP-ports (port numbers lower than 1024).
user.privileged: root user.unprivileged: sockd
Performance
# how many seconds can the client and it's peer idle without sending any data before we dump it timeout.io: 3600
Enable libwrap
When enabled, the Dante server will check with libwrap before applying the client pass/deny rules
The name to use for the Dante server in the libwrap configuration files is sockd
# Enable libwrap /etc/hosts.allow and /etc/hosts.deny access control
libwrap.hosts_access: yes
# Server privileges (No special privileges are required to use libwrap)
user.libwrap: sockd
Authentication
# The default of "none" permits anonymous access.
clientmethod: none socksmethod: none
clientmethod
# used in the client pass/ block rules
# A list of acceptable authentication methods for client-rules
# which connect to the address and port combination specified with the internal keyword
# which are applied before or during the SOCKS protocol negotiation.
socksmethod
# socks used in the pass/block rules
# which are applied after SOCKS protocol negotiation has completed
Remark
If no mention of the authentication method is done in later client and socks-rules,
they will default to containing all listed in the global clientmethod and method fields.
* Only methods that are part of the global method specification can be part of the methods set in a local rule.
Method
- username
- pam
* password is transmitted in cleartext with pam, username authentication method
Setting: Server privileges
user.privileged : root
user.notprivileged : socks
username
This method requires the client to provide a username and password.
This information must match the username and password given in the system password file
* This authentication method cannot be used as a clientmethod
(client-rules, where only the IP-address of the connecting client is available)
* The "username" socksmethod cannot be used for incoming traffic (bindreply, udpreply)
pam
Dante must be compiled with support for PAM in order to be able to use the PAM authentication method
sockd -vv | grep build: | grep pam
build: libwrap mon-data mon-disconnect pam sess2
The default PAM service name used by Dante is sockd
* the default is for the PAM system to pass all traffic if a non-existing file is specified(pamservicename)
pam.address
IP-based (rhosts) PAM authentication.
pam.username
Username/password-based PAM authentication.
Similar to the method username, but the information is passed to the PAM
subsystem for authentication, rather than Dante using the system password file directly.
When using PAM, be wary of memory leakages and other bugs in the external PAM library Dante will have to use on your platform.
pam.any
Will try to match against any type of PAM authentication,
depending on the information that is currently available.
Normally of limited use, and you should instead set the pam-based method(s) you actually want.
Example
# Allow connections from authenticated users on internal network
client pass { from: 0.0.0.0/0 to: 0.0.0.0/0 log: error # connect disconnect } #allow connections from authenticated users in group "socksusers" client pass { from: 0.0.0.0/0 to: 0.0.0.0/0 log: error # connect disconnect socksmethod: username group: socksusers }
ACL
* rule processing stops at the first match
* The Dante SOCKS server will by default block all incoming / through connections,
so at least one client & scok pass rules is needed.
client rule
Apply to internal clients (specified with the internal keyword)
* rules are applied before any data is read from the client
* actual SOCKS operation requested by the client might still be denied by the SOCKS command rules
rules operate at the TCP level
In the client-rule context, to means the address the request is accepted on
(a address the Dante server listens on)
i.e.
client pass { from: s.s.s.s/32 to: 0.0.0.0/0 log: error # connect, disconnect }
socks rule
The "client" rules control access to the SOCKS server,
while the "socks" rules control access through it.
The former can limit the machines that can connect on the internal side,
and the latter how they can communicate with the external machines.
operate at the socks protocol level
# block connections to localhost, or they will appear to come from the proxy.
block { from: 0.0.0.0/0 to: lo log: connect }
The Dante SOCKS server supports five commands that can be used in the rule statements
Commands: bind, connect, udpassociate, bindrepy, udpreply
These fall into two groups:
- the first three correspond to requests made by the internal clients (connect(常用), bind(tcp) , udpassociate(udp))
- the remaining two (bindreply and udpreply) correspond to the result of communication made by external hosts,
either a TCP connection made to a port binding created with bind, or an UDP packet sent to a port bound with udpassociate
(external host -> internal client)
bind
BIND request 相當於 router 的 uPNP
應用情況: use with multi-connection protocols (like FTP)
proxyprotocol
# None of these rules use the keyword, implying that both version 4 and version 5 is accepted.
# user authentication => SOCKS version 5 (SOCKS 4 不支援 login)
i.e.
#generic pass statement - bind/outgoing traffic
socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 command: bind connect udpassociate proxyprotocol: socks_v5 log: error # connect, disconnect, iooperation }
socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 command: bindreply udpreply log: error # connect, disconnect, iooperation }
My Configure
# without any authentication, control by IP
logoutput: /var/log/sockd.log
errorlog: /var/log/sockd.errlog
internal: ens192 port = 10080
external: ens192
user.privileged: sockd
user.unprivileged: sockd
user.libwrap: sockd
timeout.io: 3600
clientmethod: none
socksmethod: none
client pass {
from: s.s.s.s/32 to: 0.0.0.0/0
log: error connect disconnect
}
socks pass {
from: 0.0.0.0/0 to: 0.0.0.0/0
command: bind connect udpassociate
proxyprotocol: socks_v5
log: error connect disconnect
}
socks pass {
from: 0.0.0.0/0 to: 0.0.0.0/0
command: bindreply udpreply
log: error connect disconnect
}
Proxy with Login
Setting
clientmethod: none socksmethod: username none client pass { from: 0.0.0.0/0 to: 0.0.0.0/0 log: error connect disconnect } socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 proxyprotocol: socks_v5 command: bindreply udpreply log: error connect disconnect } ########################################## # IP socks pass { from: x.x.x.x/32 to: 0.0.0.0/0 proxyprotocol: socks_v5 command: bind connect udpassociate log: error connect disconnect socksmethod: none } # username socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 proxyprotocol: socks_v5 command: bind connect udpassociate log: error connect disconnect socksmethod: username group: socksusers }
# 失敗
# no login
... sockd[2817]: info: pass(1): tcp/accept [: s.s.s.s:port p.p.p.p.10080 ... sockd[2819]: info: block(1): tcp/accept ]: s.s.s.s:port p.p.p.p.10080: blocked by higher-level socks-rule #0: no rules matched; using default block rule
# 錯 PW
... sockd[2857]: info: pass(1): tcp/accept [: s.s.s.s.58647 p.p.p.p.10080 ... sockd[2857]: info: block(1): tcp/accept ]: s.s.s.s.58647 p.p.p.p.10080: error after reading 23 bytes in 0 seconds: system password authentication failed for user "tim"
# 沒有此 User A/C
... sockd[2863]: info: pass(1): tcp/accept [: s.s.s.s.58652 p.p.p.p.10080 ... sockd[2863]: info: block(1): tcp/accept ]: s.s.s.s.58652 p.p.p.p.10080: error after reading 24 bytes in 0 seconds: could not access user "tima"'s records in the system password file: no system error
# 成功
# IP
... sockd[2863]: info: pass(1): tcp/accept [: s.s.s.s.9317 p.p.p.p.10080 ... sockd[2861]: info: pass(2): tcp/connect [: s.s.s.s.9317 p.p.p.p.10080 -> p.p.p.p.9317 f.f.f.f.80 ... sockd[2861]: info: pass(2): tcp/connect ]: 923 -> s.s.s.s.9317 p.p.p.p.10080 -> 305, 305 -> p.p.p.p.9317 f.f.f.f.80 -> 923: local client error (Connection reset by peer). Session duration: 0s ... sockd[2861]: info: pass(1): tcp/accept ]: 923 -> s.s.s.s.9317 p.p.p.p.10080 -> 305: local client error (Connection reset by peer). Session duration: 0s
[: 連線
]: 斷線
# User A/C
... sockd[2857]: info: pass(1): tcp/accept [: s.s.s.s.58637 p.p.p.p.10080 ... sockd[2837]: info: pass(3): tcp/connect [: username%[email protected] p.p.p.p.10080 -> p.p.p.p.58637 f.f.f.f.80 ... sockd[2837]: info: pass(3): tcp/connect ]: 923 -> username%[email protected] p.p.p.p.10080 -> 305, 305 -> p.p.p.p.58637 f.f.f.f.80 -> 923: local client error (Connection reset by peer). Session duration: 0s ... sockd[2837]: info: pass(1): tcp/accept ]: 923 -> s.s.s.s.58637 p.p.p.p.10080 -> 305: local client error (Connection reset by peer). Session duration: 0s
Test with curl
curl -v -x socks5://user:pass@<PROXY_IP>:1080 http://www.google.com/
Control the number of active sessions
The keywords fall into two groups
- a total limit for all clients matching the rule the keywords
- specify a limit on any unique client IP-address
* both limits will be enforced.
* Limits are enforced on both TCP and UDP sessions
(In the case of UDP sessions, the limit of a socks-rule will be enforced based on the address of client's TCP control connection)
Total limit
session.max
The total number of concurrent sessions allowed for clients matching the rule.
session.throttle
The maximum rate at which session can be created. # LIMIT/SECONDS
Per client IP-address
session.state.key
session.state.max
session.state.throttle
Setting Example
client pass { from: 0.0.0.0/0 to: 0.0.0.0/0 log: connect disconnect error #limit for all clients session.max: 10000 session.throttle: 100/1 #per-ip limit session.state.key: from session.state.max: 100 session.state.throttle: 10/2 }
當 over 時會有 log
session.max
session limit reached (LIMIT/LIMIT slots in use)
session.throttle
session rate limit reached (already accepted LIMIT new clients during the last SECONDSs. Current client count: LIMIT)
session.state.max
per-key session limit reached (LIMIT/LIMIT slots in use)
session.state.throttle
per-key session rate limit reached (already accepted LIMIT new clients during the last SECONDSs. Current client count: LIMIT)
Remark
* ssh 到同一目的地只計一個 Session
Network Timeout Setting
# server will wait for a connect initiated on behalf of the socks-client to complete
# 0 will use the systems default
# default 30
timeout.connect 30
# established connection can be idle
# default is 0, meaning forever
timeout.io 0
# a client can spend negotiating with the Dante server for a socks session
# before Dante will close the connection to the client.
# The default is 30.
# Set it to 0 for forever
timeout.negotiate 30
# The timeout for the equivalent of TCP's FIN-WAIT-2.
# The default is 0, which means use the systems default
timeout.tcp_fin_wait 0
Performance Setting
CPU settings
The CPU settings for the various type of Dante processes.
There are four process types: mother, negotiate, request, and io
Example 1:
# requests the kernel schedules the mother process(s) using a first-in,first-out policy, at priority 20
cpu.schedule.mother: SCHED_FIFO/20
* The default is to not request any specific scheduling
Example 2:
# Specifying one or more numeric CPU id limits the process to that set of CPUs.
cpu.mask.mother: any
cpu.mask.io: 0 1
* The default: any
If they are to be used, the io processes are where most of the work is done and adjusting the priority
or CPU usage is what is likely to have the most significant performance effect client performance
and overhead from the server.
The other processes are primarily used during connection/session establishment
and changes to settings for the non-io process types will primarily affect these operations.
Reload & logrotate
Reload
SIGHUP Reload the configuration file. Will also reopen logfiles.
... sockd[6683]: info: SIGHUP [: reloading config ... sockd[6683]: info: SIGHUP ]: config reloaded. Broadcasting to children to do the same ... sockd[6684]: info: sighup_child(): received SIGHUP: reloading config
reload_dante.sh
#!/bin/bash /usr/bin/kill -s SIGHUP $(cat /var/run/sockd.pid) tail -n 1 /var/log/sockd.log
logrotate
/etc/logrotate.d/sockd
/var/log/sockd.errlog /var/log/sockd.log { missingok daily rotate 14 dateext delaycompress sharedscripts postrotate kill -s SIGHUP $(cat /var/run/sockd.pid) endscript }
Doc
- https://www.inet.no/dante/doc/1.4.x/sockd.conf.5.html
- https://www.inet.no/dante/doc/1.4.x/config/index.html