Category Archives: Linux

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

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

Install the kerberos things. The AD domain is UNKNOWN.

aptitude install krb5-user libpam-krb5

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 = unkown.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

You will be prompted the administrator passowrd:

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

apt-get install samba winbind

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

Give administrator password:

Enter administrateur's password:
Using short domain name -- UNKNOWN
Joined '
kikinou' to dns domain 'unknown.local'

Greetings, linux kikinou server joined the domain « UNKNOWN »
You are now able to view AD users and groups from the linux server:

wbinfo -u
wbinfo -g

Edit /etc/nsswitch.conf to add winbind for looking up passwords and 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.
In case getent does not return anything else than local information (no AD info), check you have the library that connects winbind to nss. If not install it:

apt-get install libnss-winbind

Edit file /etc/pam.d/common-session and add the two last lines (for debian):

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

That’s it, you can now log on your debian server with a windows AD user.

sshd fatal: cipher & key exhange

I did some update on an old debian system and then SSH server refused to let me in.
I got the message:

sshd[19482]: fatal: no matching cipher found:

Just have a look in your /var/log/auth file and determine what cipher the client and server are using. This error message means there is no common cipher between the client and the server.

I added in /etc/ssh/sshd_config file the lines:

Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,blowfish-cbc,aes128-cbc,3des-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc

Then I got a new error message:

sshd[20362]: fatal: Unable to negotiate a key exchange method [preauth]

Just precise key exchange method by adding the following line in your /etc/ssh/sshd_config file:

KexAlgorithms=curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1