Category Archives: Linux

Squid transparent AD authentication

This article describes how to make transparent squid authentication against active directory.
Prerequisite: your linux box has joined the domaine, see article: Debian active directory authentication

Just remember to check your DNS config in resolv.conf:

domain unknown.local
search unknown.local
nameserver 10.10.22.30
nameserver 10.10.22.100

Make a reverse check with

# dig -x <nameserver ip>

Ensute time is correct

# ntpdate <windows DC>

Generate keytab file:

# kinint administrateur
# msktutil -c -b "CN=COMPUTERS" -s HTTP/serverproxy.unknown.local -k /etc/the.keytab --computer-name serverproxy --upn HTTP/serverproxy.unknown.local --server dc.unknown.local --enctypes 28

keytab file must be readable from processes that will use it, for example squid.
In case of errors you can check if you got a ticket after kinit:

# klist

You can also check if the keytab was successfully generated with servers

# klist -k /etc/the.keytab

Ensure keytab is renewed, put in cron:

00 4  *   *   *     msktutil --auto-update --verbose --computer-name serverproxy | logger -t msktutil

Squid configuration:

### Authentification automatique via Kerberos
auth_param negotiate program /usr/lib/squid/negotiate_kerberos_auth -d -s HTTP/serverproxy.unknown.local@UNKNOWN.LOCAL
auth_param negotiate children 20 startup=30
auth_param negotiate keep_alive off

Include variables before starting squid, you can put it in /etc/profile

KRB5_KTNAME=/etc/squid/squid.keytab
export KRB5_KTNAME

In the browser you must configure the proxy with it’s FQDN:

serverproxy.unknown.local

iptables INVALID use case

This article describes a use case of iptables INVALID state.

LAN 192.168.0.0/24 is connected to the gateway 192.168.0.1 eth1.
VPN server 192.168.0.100 offers VPN services on network 10.0.0.0/24, for example a client will have the address 10.0.0.237.
VPN server has two interfaces 192.168.0.100 and 10.0.0.1, forwarding is enabled.
All routes are maintained ONLY on the gateway 192.168.0.1.

When VPN client 10.0.0.237 wants to reach a server located on the LAN, 192.168.0.50 for example, it does not work !!!

Let’s have a look at routes.
Way to go:
VPN client 10.0.0.237 wants to reach 192.168.0.50.
First it goes to its gateway 10.0.0.1,
then it reach the 192.168.0.100 still on the gateway
and 192.168.0.50 is on the connected interface 192.168.0.100, then it reaches the server
Way back:
server 192.168.0.100 has a default gateway 192.168.0.1,
and then nothing happen, packet are stopped on the gateway 192.168.0.1, it means packet are not sent back and it does not work.

Why ?
This is because LAN server 192.168.0.100 send returns packet back to the default gateway 192.168.0.1 instead of VPN server 192.168.0.100.
Default gateway does not accept this: packet are not NEW nor ESTABLISHED. This is asymetric routing.

In order to make this possible there are several solutions:
– add on all LAN server a route like 10.0.0.0/24 via 192.168.0.100, but I do not want this solution since I only maintain routes on the gateway
– other solution is to make gateway accept packets that are not NEW or ESTABLISHED:

$I -A FORWARD -i eth1 -o eth1 -s 192.168.0.0/24 -d 10.0.0.0/24 -m state --state INVALID -j ACCEPT

This rule says packet coming from LAN (on 192.168.0.1) exiting on LAN (from 192.168.0.1) to destination VPN network (10.0.0.0/24) are accepted even though they do not have a normal state (INVALID).
You are accepting asymetric routing on your network and now it works: VPN clients do have access to all LAN servers.

And to not forget legitim trafic:

$I -A FORWARD -i eth1 -o eth1 -s 192.168.0.0/24 -d 10.0.0.0/24 -m state --state NEW,ESTABLISHED -j ACCEPT

Debian active directory authentication

In this article AD domain is UNKNOWN.LOCAL (UNKNOWN). Domaine crontroller is carotte.


Ensure the debian server date and the AD server do have the same date and time. If needed install ntpd or ntpdate.

# ntpdate carotte

Check your DNS configuration:

domain unknown.local
search unknown.local
nameserver carotte

Install packages:

# aptitude install krb5-user libpam-krb5 libnss-winbind samba winbind

Edit file /etc/krb5.conf

[logging]
default = FILE:/var/log/krb5.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
default_realm = UNKNOWN.LOCAL
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
[realms]
UNKNOWN.LOCAL = {
kdc = carotte
admin_server = carotte
}
[domain_realm]
.unknown = UNKNOWN
.UNKNOWN = UNKNOWN
.unknown.local = UNKNOWN.LOCAL
[login]
krb4_convert = true
krb4_get_tickets = false

Check it works and you can authenticate a windows AD user from the debian server:

# kinit administrator
Password for administrator@UNKNOWN.LOCAL:

No message is a good thing. Check you have been granted a kerberos ticket:

# klist

You should have the ticket:

Ticket cache: FILE:/tmp/krb5cc_0
Default principal: administrator@UNKNOWN.LOCAL

Valid starting Expires Service principal
10/15/2015 13:51:07 10/15/2015 23:51:07 krbtgt/UNKNOWN.LOCAL@UNKNOWN.LOCAL
renew until 10/22/2015 13:51:03

Now integrate the debian server in the AD domain
Change file /etc/samba.conf

[global]
workgroup = UNKNOWN
security = ads
realm = UNKNOWN.LOCAL
password server = carotte
domain logons = no
template homedir = /home/%D/%U
template shell = /bin/bash
winbind enum groups = yes
winbind enum users = yes
winbind use default domain = yes
client use spnego = yes
client ntlmv2 auth = yes
encrypt passwords = yes
winbind use default domain = yes
restrict anonymous = 2
domain master = no
local master = no
prefered master = no
os level = 0
idmap config *:backend = tdb
idmap config *:range = 11000-20000
idmap config UNKNOWN:backend = rid
idmap config UNKNOWN:range = 10000000-1900000000

Restart services:

# /etc/init.d/winbind stop
# /etc/init.d/samba restart
# /etc/init.d/winbind start

Now join the domain:

# net ads join -U administrator
Enter administrateur's password:
Using short domain name -- UNKNOWN
Joined '
kikinou' to dns domain 'unknown.local'

You need a script at startup that ensures you’re on the domain:

#!/bin/sh
/usr/bin/net ads join -U administrateur%"Merde00AD"
while [ $? != 0 ];
do
    sleep 2
    /usr/bin/net ads join -U administrateur%"Merde00AD"
done
logger "Domain rejoint au demarrage"
service winbind restart
sleep 1;
wbinfo -u > /dev/null

Since server has joined the domain, you can perform some checks.
Check RPC connection with the domaine

# wbinfo -t
checking the trust secret for domain UNKNOWN via RPC calls succeeded

Display active directory server that is replying to linux server:

# wbinfo -P
checking the NETLOGON for domain[UNKNOWN] dc connection to "CAROTTE.unknown.local" succeeded

You are now able to view AD users from the linux server:

# wbinfo -u

You are now able to view AD groups from the linux server:

# wbinfo -g

Edit /etc/nsswitch.conf to add winbind for looking up domain passwords and domain groups.
Add windbind at the end of these two lines:

passwd: compat winbind
group: compat winbind

Make a test by getting AD users and groups

# getent passwd

You should get a view of passwd file with also AD users informations.

# getent group

The same as above but showing group with AD groups.

Edit file /etc/pam.d/common-session and add the two last lines (for debian), it creates home dir for users that never logged on the server:

session [default=1] pam_permit.so
session requisite pam_deny.so
session required pam_permit.so
session required pam_unix.so
session required pam_mkhomedir.so umask=0022 skel=/etc/skel

TROUBLESHOOOTING
Error with wbinfo -t

checking the trust secret for domain UNKNOWN via RPC calls failed
wbcCheckTrustCredentials(UNKNOWN): error code was NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND (0xc0000233)
failed to call wbcCheckTrustCredentials: WBC_ERR_AUTH_ERROR

Solution: join again the domain

net ads join -U administrateur