dante

最後更新: 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%tim@s.s.s.s.58637
                                            p.p.p.p.10080 -> p.p.p.p.58637 f.f.f.f.80

... sockd[2837]: info: pass(3): tcp/connect ]: 923 -> username%tim@s.s.s.s.58637 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