Wiki source code of OpenVPN

Last modified by Sebastian Marsching on 2022/05/29 13:52

Show last authors
1 {{toc/}}
2
3 # MTU issues with OpenVPN
4
5 When packages that are travelling through an OpenVPN tunnel seem to disappear or connections (seem to not react any more (e.g. a webpage keeps loading and loading), this issues might be related to problems with the [MTU](http://en.wikipedia.org/wiki/Maximum_transmission_unit) settings.
6
7 fragment 1300
8 mssfix
9
10 You might have to change the fragment value, but 1300 should be okay for a first try.
11
12 See also: [[Path MTU Discovery issues|doc:Network.IP.WebHome|anchor="HPathMTUDiscoveryIssues"]]
13
14 # Authenticating with Active Directory
15
16 The following script can be used with OpenVPNs `auth-user-pass-verify` directive. The script reads the username and password from a file, so the `via-file` method should be specified. This script needs a fairly modern version of the `ldap3` module (it has been tested with version 1.3.1).
17
18 ```python
19 #!/usr/bin/python
20
21 # Authenticates an OpenVPN user against an Active Directory using LDAP.
22 # The authentication is successful when the specified credentials can be used to
23 # successfully connect with the LDAP service and the user is a member of the
24 # specified group. The membership check includes transitive memberships.
25 # The username is expected to be the SAM account name (without the domain).
26 # The password is expected to be the raw (unhashed) password.
27 # The username and password are read from the file specified as the only
28 # parameter to this script so that do not have to be passed through
29 # potentially unsafe environment variables.
30
31 import io
32 import ldap3
33 import sys
34
35 # Find the principal (LDAP object) for the specified SAM account name.
36 # The SAM account name must not include the domain.
37 def find_principal_by_sam_account_name(ldap_connection, base_dn, sam_account_name):
38 if not ldap_connection.search(search_base = base_dn, search_filter = ('(sAMAccountName=' + ldap3.utils.conv.escape_filter_chars(sam_account_name) + ')')):
39 return None
40 if len(ldap_connection.entries) == 0:
41 return None
42 return ldap_connection.entries[0]
43
44 # This method is useful if we need all groups that the user is a member of.
45 def find_all_groups_principal_is_member_of(ldap_connection, base_dn, principal_dn):
46 if not ldap_connection.search(search_base = base_dn, search_filter = ('(member:1.2.840.113556.1.4.1941:=' + ldap3.utils.dn.safe_dn(principal_dn) + ')'), attributes = ldap3.ALL_ATTRIBUTES):
47 return None
48 return ldap_connection.entries
49
50 # Checks whether the specified principal (identified by its DN) is a member of
51 # the specified group (identified by its SID).
52 def is_principal_member_of_group(ldap_connection, base_dn, principal_dn, group_sid):
53 if not ldap_connection.search(search_base = base_dn, search_filter = ('(&(objectSid=' + ldap3.utils.conv.escape_filter_chars(group_sid) + ')(member:1.2.840.113556.1.4.1941:=' + ldap3.utils.dn.safe_dn(principal_dn) + '))')):
54 return False
55 return len(ldap_connection.entries) != 0
56
57
58 # We use short timeouts so that we can failover to another domain controller
59 # when the first one fails.
60 connect_timeout = 1.0
61 receive_timeout = 1.0
62 base_dn = 'dc=ad,dc=example,dc=com'
63 # We can restrict the tree in which the principal must reside. If no
64 # restrictions are desired, we can simply use the base DN.
65 principal_search_base_dn = base_dn
66 domain = 'WINDOMAIN'
67 group_sid = 'S-1-5-21-1234567890-1234567890-1234567890-1234'
68 ldap_servers = [ 'dc-1.ad.example.com', 'dc-2.ad.example.com' ]
69
70 if len(sys.argv) != 2:
71 sys.exit(1)
72
73 user_pass_filename = sys.argv[1]
74 try:
75 user_pass_file = io.open(user_pass_filename)
76 username = user_pass_file.readline().strip()
77 password = user_pass_file.readline().strip()
78 user_pass_file.close()
79 except:
80 sys.exit(1)
81
82 ldap_username = domain + '\\' + username
83
84 connection = None
85 server = None
86 for ldap_server in ldap_servers:
87 try:
88 server = ldap3.Server(ldap_server, port = 636, use_ssl = True, connect_timeout = connect_timeout)
89 connection = ldap3.Connection(server, user = ldap_username, password = password, auto_bind = True, receive_timeout = receive_timeout)
90 break
91 except:
92 server = None
93 connection = None
94
95 if connection == None:
96 sys.exit(1)
97
98 try:
99 user_entry = find_principal_by_sam_account_name(connection, principal_search_base_dn, username)
100 if user_entry == None:
101 sys.exit(1)
102 user_dn = user_entry.entry_get_dn()
103 is_group_member = is_principal_member_of_group(connection, base_dn, user_dn, group_sid)
104 except:
105 sys.exit(1)
106
107 if is_group_member:
108 sys.exit(0)
109 else:
110 sys.exit(1)
111 ```