NGINX Reverse Proxy für Exchange 2016

Folgende Pakete müssen auf einem Ubuntu 16.04 LTS installiert werden:

apt install nginx nginx-extras

Die Konfiguration wird abgelegt unter /etc/nginx/conf.d/exchange.conf

Folgende Dinge müssen angepasst werden:

  • DNS Name unter dem OWA etc. erreichbar sein soll z.B. mail.example.org
  • Autodiscover DNS Name z.B. autodiscover.example.org
  • Interner Exchange Server z.B. exchange-server.example.internal
server {
    listen 80;
    server_name mail.example.org autodiscover.example.org;
    return 301 https://$host$request_uri;
}

server {
    tcp_nodelay on;
    listen 443;
    ssl                     on;
    ssl_certificate /etc/ssl/certs/star.example.org.pem;
    ssl_certificate_key /etc/ssl/private/star.example.org.key;

    ssl_session_timeout     5m;
    server_name mail.example.org;

    location / {
            return 301 https://mail.example.org/owa;
    }

    proxy_http_version      1.1;
    proxy_read_timeout      360;
    proxy_pass_header       Date;
    proxy_pass_header       Server;
    proxy_pass_header       Authorization;
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_pass_request_headers on;
    more_set_input_headers 'Authorization: $http_authorization';
    proxy_set_header Accept-Encoding "";
    more_set_headers -s 401 'WWW-Authenticate: Basic realm="exchange-server.example.internal"';
    # proxy_request_buffering off;
    proxy_buffering off;
    proxy_set_header Connection "Keep-Alive";

    location ~* ^/owa { proxy_pass https://exchange-server.example.internal; }
    location ~* ^/Microsoft-Server-ActiveSync { proxy_pass https://exchange-server.example.internal; }
    location ~* ^/ecp { proxy_pass https://exchange-server.example.internal; }
    location ~* ^/rpc { proxy_pass https://exchange-server.example.internal; }
    location ~* ^/autodiscover { proxy_pass https://exchange-server.example.internal; }
    location ~* ^/oab { proxy_pass https://exchange-server.example.internal; }

    error_log /var/log/nginx/exchange-rproxy-ssl-error.log;
    access_log /var/log/nginx/exchange-rproxy-ssl-access.log;
}

Ob alles einwandfrei Funktioniert lässt sich über einen Webservice von Microsoft testen:

https://testconnectivity.microsoft.com/

 

Quellen:

Viel Spaß 😉

Check_MK: Problem mit Apache HTTP Proxy – SELinux blockt Reverse Proxy Verbindung zur Check_MK Instanz

Habe gerade auf ein frisch installiertes CentOS 7.4 Check_MK 1.4.0p19 installiert. Nach dem Start einer OMD Instanz kommt nur die Fehlermeldung:

OMD: Site Not Started

You need to start this site in order to access the web interface.

Im Apache Log ist folgendes zu sehen:

[Mon Dec 04 08:50:48.097245 2017] [proxy_http:error] [pid 20887] [client x.x.x.x:31372] AH01114: HTTP: failed to make connection to backend: 127.0.0.1, referer: http://server.example.net/extern/
[Mon Dec 04 08:50:56.943253 2017] [proxy:error] [pid 20883] (13)Permission denied: AH00957: HTTP: attempt to connect to 127.0.0.1:5000 (127.0.0.1) failed
[Mon Dec 04 08:50:56.943276 2017] [proxy:error] [pid 20883] AH00959: ap_proxy_connect_backend disabling worker for (127.0.0.1) for 0s
[Mon Dec 04 08:50:56.943280 2017] [proxy_http:error] [pid 20883] [client x.x.x.x:31408] AH01114: HTTP: failed to make connection to backend: 127.0.0.1

netstat – tulpen zeigt aber das das Backend läuft:

# netstat -tulpen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode      PID/Program name    
...
tcp        0      0 127.0.0.1:5000          0.0.0.0:*               LISTEN      997        71127      21004/httpd         
...

Ein Blick in das Audit Log verrät das SELinux zuschägt:

#tail -f /var/log/audit/audit.log
...
type=AVC msg=audit(1512377448.096:3647): avc:  denied  { name_connect } for  pid=20887 comm="httpd" dest=5000 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:commplex_main_port_t:s0 tclass=tcp_socket
type=SYSCALL msg=audit(1512377448.096:3647): arch=c000003e syscall=42 success=no exit=-13 a0=a a1=559b02b25650 a2=10 a3=7fffb621631c items=0 ppid=20882 pid=20887 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(1512377508.204:3689): avc:  denied  { name_connect } for  pid=21020 comm="httpd" dest=5000 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:commplex_main_port_t:s0 tclass=tcp_socket
type=SYSCALL msg=audit(1512377508.204:3689): arch=c000003e syscall=42 success=no exit=-13 a0=a a1=559b02b25650 a2=10 a3=7fffb621633c items=0 ppid=20882 pid=21020 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null)
...

Das Problem kann temporär zum testen wie folgt gelöst werden:

/usr/sbin/setsebool httpd_can_network_connect 1

um die Änderung permanent zu übernehmen:

/usr/sbin/setsebool -P httpd_can_network_connect 1

 

Subnetze und IP Adressen extrahieren aus SPF Records (z.B. Office365 oder Google Apps for Business)

Wenn man bei Office365 oder Google Apps for Business einen eigenen Mailserver (Postfix) vorschalten möchte beim versenden/empfangen muss man die Mailserver von Microsoft/Google Whitelisten in den mynetworks bei Postfix.

Das Script löst alle SPF Record includes auf und generiert CIDR Maps die sich in Postfix einbinden lassen.

Beispiel:

max@dev1:~$ python get_subnets_of_spf_record_mynetwoks.py
Working on job office365
Working on job google

Es werden 2 Files erzeugt:

max@dev1:~$ cat /etc/postfix/networks/google 
64.18.0.0/20 OK
64.233.160.0/19 OK
66.102.0.0/20 OK
66.249.80.0/20 OK
72.14.192.0/18 OK
74.125.0.0/16 OK
108.177.8.0/21 OK
173.194.0.0/16 OK
207.126.144.0/20 OK
209.85.128.0/17 OK
216.58.192.0/19 OK
216.239.32.0/19 OK
[2001:4860:4000::]/36 OK
[2404:6800:4000::]/36 OK
[2607:f8b0:4000::]/36 OK
[2800:3f0:4000::]/36 OK
[2a00:1450:4000::]/36 OK
[2c0f:fb50:4000::]/36 OK
172.217.0.0/19 OK
108.177.96.0/19 OK
max@dev1:~/test$ cat /etc/postfix/networks/office365
207.46.101.128/26 OK
207.46.100.0/24 OK
207.46.163.0/24 OK
65.55.169.0/24 OK
157.56.110.0/23 OK
157.55.234.0/24 OK
213.199.154.0/24 OK
213.199.180.0/24 OK
157.56.112.0/24 OK
207.46.51.64/26 OK
157.55.158.0/23 OK
64.4.22.64/26 OK
40.92.0.0/14 OK
40.107.0.0/17 OK
40.107.128.0/17 OK
134.170.140.0/24 OK
[2a01:111:f400::]/48 OK
23.103.128.0/19 OK
23.103.198.0/23 OK
65.55.88.0/24 OK
104.47.0.0/17 OK
23.103.200.0/21 OK
23.103.208.0/21 OK
23.103.191.0/24 OK
216.32.180.0/23 OK
94.245.120.64/26 OK
[2001:489a:2202::]/48 OK

In Posftix werden sie in der main.cf eingebunden:

# ----------------------------------------------------------------------
# My Networks
# ----------------------------------------------------------------------
mynetworks =
        cidr:/etc/postfix/networks/local
        cidr:/etc/postfix/networks/other
        cidr:/etc/postfix/networks/google
        cidr:/etc/postfix/networks/office365

Da sich zwischendurch die Records auch mal ändern können empfiehlt es sich einen Cronjob dafür einzurichten. Ich habe eine Variante mit diff die nur patcht wenn das Resultat nicht null ist.

Das Script lässt sich auch noch für andere Dienste / etc. anpassen:

lookup_spf = {
# Google Apps for Business
"google": {
          "domain": "google.com",
          "file"  : "/etc/postfix/networks/google",
          },

# Office365
"office365": {
          "domain": "spf.protection.outlook.com",
          "file"  : "/etc/postfix/networks/office365",
          },

# Example
"example": {
          "domain": "example.com",
          "file"  : "/etc/postfix/networks/example",
          },

}

Sourcecode:

#!/usr/bin/env python

#
# get_subnets_of_spf_record_mynetwoks.py
# Resolve all known ip addresses from spf record and generate cidr map for postfix
#
# Version 1.0
# Written by Maximilian Thoma (http://www.lanbugs.de)
#
# The generated files can be used in postfix config with for example mynetworks = cidr:/etc/postfix/<generated_file>
#
# This program is free software; you can redistribute it and/or modify it under the terms of the
# GNU General Public License as published by the Free Software Foundation;
# either version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with this program;
# if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 
# MA 02110, USA
#

#
# Requirements:
# dnspython module  -> pip install dnspython
#

import dns.resolver
from dns.exception import DNSException
import re
import sys

# Look for DNS Record at:
#
# "jobname": {
#            "domain": "domainname",
#            "file": "output_file",
#            }
#

# 

lookup_spf = {
# Google Apps for Business
"google": {
          "domain": "google.com",
          "file"  : "/etc/postfix/networks/google",
          },

# Office365
"office365": {
          "domain": "spf.protection.outlook.com",
          "file"  : "/etc/postfix/networks/office365",
          },
}

############################################################################################

def getspf(record, filehandler):
    # Init Resolver
    myResolver = dns.resolver.Resolver()

    try:
        # Try to lookup TXT record
        myAnswer = myResolver.query(record,"TXT")

    except DNSException:
        sys.stderr.write("Failed to query record, SPF broken.")
        return

    results = []

    for rdata in myAnswer:
        # Get string out of records
        for txt_string in rdata.strings:
            # Append to SPF Records buffer if "spf" in string
            if "spf" in txt_string:
                results.append(txt_string)

    # If results >=1
    if len(results) >= 1:
        # Work on records
        for spf in results:
            # Split parts
            parts = spf.split(" ")
            # Check parts
            for part in parts:

                s_include = re.match(r"^include:(?P<domain>.*)$", part)
                s_ip4 = re.match(r"^ip4:(?P<ip4>.*)$", part)
                s_ip6 = re.match(r"^ip6:(?P<ip6>.*)$", part)

                # If in part "include" found, next round
                if s_include:
                    getspf(s_include.group('domain'), filehandler)
                # elif ip4 found
                elif s_ip4:
                    filehandler.write(s_ip4.group('ip4') + " OK\n")
                # elif ip6 found
                elif s_ip6:
                    filehandler.write("[" + s_ip6.group('ip6').replace("/","]/") + " OK\n")
                # else no valid record
                else:
                    pass
    # no results 
    else:
        sys.stderr.write("No results")
        pass

def main():
    # Working on jobs
    for jobname, config in lookup_spf.iteritems():

        print "Working on job %s" % jobname

        # open file
        filehandler = open(config['file'], 'w')
        # start query spf records
        getspf(config['domain'], filehandler)
        # close file
        filehandler.close()


#getspf(lookup_spf)

if __name__ == "__main__":
    main()

 

HP Server Tools für Debian/Ubuntu

HP stellt für verschiedene Linux Distributionen seine eigenen Tools bereit. Unteranderem System Health Application and Command line Utilities, iLO Online Configuration Utilities und die Insight Management Agents.

HP SDR (Software Delivery Repository): http://downloads.linux.hpe.com/SDR/index.html

Repository für Debian 8 (jessie) hinzufügen

/etc/apt/sources.list.d/HP-mcp.list anlegen

deb http://downloads.linux.hpe.com/SDR/repo/mcp jessie/current non-free

Alternativ Repository für Ubuntu 16.04 LTS hinzufügen

/etc/apt/sources.list.d/HP-mcp.list anlegen

deb http://downloads.linux.hpe.com/SDR/repo/mcp xenial/current non-free

Repository PGP Keys importieren (curl wird benötigt)

curl http://downloads.linux.hpe.com/SDR/hpPublicKey1024.pub | apt-key add -
curl http://downloads.linux.hpe.com/SDR/hpPublicKey2048.pub | apt-key add -
curl http://downloads.linux.hpe.com/SDR/hpPublicKey2048_key1.pub | apt-key add -
curl http://downloads.linux.hpe.com/SDR/hpePublicKey2048_key1.pub | apt-key add -

Paketquellen updaten

apt update

Pakete installieren (hp-health, hponcfg, hp-snmp-agents)

apt install hp-health hponcfg hp-snmp-agents

HP-Health (hpasmcli)

Das Kommando für die Health Tools ist hpasmcli.

root@rzm-srv01e13:~# hpasmcli
HPE management CLI for Linux (v2.0)
Copyright 2015 Hewlett Packard Enterprise Development LP.

--------------------------------------------------------------------------
NOTE: Some hpasmcli commands may not be supported on all Proliant servers.
      Type 'help' to get a list of all top level commands.
--------------------------------------------------------------------------
hpasmcli> 

Beispiele

show server

hpasmcli> show server
System        : ProLiant DL360 G7
Serial No.    : XXXXXXXXXX      
ROM version   : P68 08/16/2015
UEFI Support  : No
iLo present   : Yes
Embedded NICs : 4
  NIC1 MAC: d8:9d:67:aa:aa:aa
  NIC2 MAC: d8:9d:67:bb:bb:bb
  NIC3 MAC: d8:9d:67:cc:cc:cc
  NIC4 MAC: d8:9d:67:dd:dd:dd

Processor: 0
  Name         : Intel(R) Xeon(R) CPU E5640 @ 2.67GHz            
  Stepping     : 2
  Speed        : 2667 MHz
  Bus          : 133 MHz
  Core         : 4
  Thread       : 8
  Socket       : 1
  Level1 Cache : 128 KBytes
  Level2 Cache : 1024 KBytes
  Level3 Cache : 12288 KBytes
  Status       : Ok

Processor: 1
  Name         : Intel(R) Xeon(R) CPU E5640 @ 2.67GHz            
  Stepping     : 2
  Speed        : 2667 MHz
  Bus          : 133 MHz
  Core         : 4
  Thread       : 8
  Socket       : 2
  Level1 Cache : 128 KBytes
  Level2 Cache : 1024 KBytes
  Level3 Cache : 12288 KBytes
  Status       : Ok

Processor total  : 2

Memory installed : 49152 MBytes
ECC supported    : Yes

show temp

hpasmcli>  show temp         
Sensor   Location              Temp       Threshold
------   --------              ----       ---------
#1        AMBIENT              22C/71F    42C/107F 
#2        PROCESSOR_ZONE       40C/104F   82C/179F 
#3        PROCESSOR_ZONE       40C/104F   82C/179F 
#4        MEMORY_BD            35C/95F    87C/188F 
#5        MEMORY_BD            38C/100F   78C/172F 
#6        MEMORY_BD            35C/95F    87C/188F 
#7        MEMORY_BD            36C/96F    78C/172F 
#8        MEMORY_BD            38C/100F   87C/188F 
#9        MEMORY_BD            37C/98F    78C/172F 
#10       MEMORY_BD            37C/98F    87C/188F 
#11       MEMORY_BD            37C/98F    78C/172F 
#12       POWER_SUPPLY_BAY     39C/102F   59C/138F 
#13       POWER_SUPPLY_BAY     50C/122F   73C/163F 
#14       MEMORY_BD            32C/89F    72C/161F 
#15       PROCESSOR_ZONE       35C/95F    73C/163F 
#16       PROCESSOR_ZONE       34C/93F    64C/147F 
#17       MEMORY_BD            35C/95F    63C/145F 
#18       PROCESSOR_ZONE       43C/109F   69C/156F 
#19       SYSTEM_BD            39C/102F   69C/156F 
#20       SYSTEM_BD            43C/109F   71C/159F 
#21       SYSTEM_BD            50C/122F   65C/149F 
#22       SYSTEM_BD            52C/125F   71C/159F 
#23       SYSTEM_BD            45C/113F   69C/156F 
#24       SYSTEM_BD            50C/122F   69C/156F 
#25       SYSTEM_BD            39C/102F   63C/145F 
#26       SYSTEM_BD            49C/120F   66C/150F 
#27       SCSI_BACKPLANE_ZONE  50C/122F   60C/140F 
#28       SYSTEM_BD            72C/161F   110C/230F

show fan

hpasmcli>  show fan 
Fan  Location        Present Speed  of max  Redundant  Partner  Hot-pluggable
---  --------        ------- -----  ------  ---------  -------  -------------
#1   SYSTEM          Yes     NORMAL  29%     Yes        0        No            
#2   SYSTEM          Yes     NORMAL  29%     Yes        0        No            
#3   SYSTEM          Yes     NORMAL  29%     Yes        0        No            
#4   SYSTEM          Yes     NORMAL  29%     Yes        0        No            

show powersupply

hpasmcli> show powersupply
Power supply #1
  Present  : Yes
  Redundant: No
  Condition: Ok
  Hotplug  : Supported
  Power    : 110 Watts
Power supply #2
  Present  : Yes
  Redundant: No
  Condition: FAILED
  Hotplug  : Supported

Kommandos lassen sich auch ohne die interaktive hpasmcli ausführen.

root@rzm-srv01e13:~# hpasmcli -s "show fan; show powersupply"

Fan  Location        Present Speed  of max  Redundant  Partner  Hot-pluggable
---  --------        ------- -----  ------  ---------  -------  -------------
#1   SYSTEM          Yes     NORMAL  30%     Yes        0        No            
#2   SYSTEM          Yes     NORMAL  30%     Yes        0        No            
#3   SYSTEM          Yes     NORMAL  30%     Yes        0        No            
#4   SYSTEM          Yes     NORMAL  30%     Yes        0        No            


Power supply #1
  Present  : Yes
  Redundant: No
  Condition: Ok
  Hotplug  : Supported
  Power    : 115 Watts
Power supply #2
  Present  : Yes
  Redundant: No
  Condition: FAILED
  Hotplug  : Supported

hponcfg (Online iLO Configuration Utility)

Über hponcfg lässt sich das iLO ohne Systemneustart konfigurieren.

root@rzm-srv01e13:~# hponcfg 
HP Lights-Out Online Configuration utility
Version 4.6.0 Date 09/28/2015 (c) Hewlett-Packard Company, 2015
Firmware Revision = 1.87 Device type = iLO 3 Driver name = hpilo

USAGE:
  hponcfg  -?
  hponcfg  -h
  hponcfg  -m minFw
  hponcfg  -r [-m minFw ]
  hponcfg  [-a] -w filename [-m minFw]
  hponcfg  -g [-m minFw]
  hponcfg  -f filename [-l filename] [-s namevaluepair] [-v] [-m minFw]
  hponcfg  -i [-l filename] [-s namevaluepair] [-v] [-m minFw]

  -h,  --help           Display this message
  -?                    Display this message
  -r,  --reset          Reset the Management Processor to factory defaults
  -b,  --reboot         Reboot Management Processor without changing any setting
  -f,  --file           Get/Set Management Processor configuration from "filename" 
  -i,  --input          Get/Set Management Processor configuration from the XML input 
                        received through the standard input stream.
  -w,  --writeconfig    Write the Management Processor configuration to "filename"
  -a,  --all            Capture complete Management Processor configuration to the file.
                        This should be used along with '-w' option
  -l,  --log            Log replies to "filename"
  -v,  --xmlverbose     Display all the responses from Management Processor
  -s,  --substitute     Substitute variables present in input config file
                        with values specified in "namevaluepairs"
  -g,  --get_hostinfo   Get the Host information
  -m,  --minfwlevel     Minimum firmware level

hp-snmp-agents (SNMP Erweiterungen für HP Sensoren)

HP liefert ein Konfigurationstool mit das Menügeführt einen durch das Grundsetup durchführt.

/sbin/hpsnmpconfig

Ich habe nur die Read/Write und ReadOnly Community geändert und alles andere auf Default lassen.

Anschließend habe ich noch Korrekturen durchgeführt in der /etc/snmp/snmpd.conf

# Anpassung der Communitys
# Schreiben nur von Loopback aus
rwcommunity supergeheim 127.0.0.1
# Lesezugriff fuer Monitoring
rocommunity public 10.10.10.200

# Listener angepasst das er nur auf der Management NW Karte erreichbar ist
agentAddress  udp:10.10.10.1:161

Restart des SNMP Daemons nicht vergessen:

service snmpd restart

 

 

Weak SSH/SSL protocols and ciphers & hardening

Sammlung aller SSH/SSL relevanten und meist genutzten Dienste und deren optimale SSH/SSL Konfiguration.

Apache / Nginx

apache 2.4.18 | modern profile | OpenSSL 1.0.1e

Oldest compatible clients: Firefox 27, Chrome 30, IE 11 on Windows 7, Edge, Opera 17, Safari 9, Android 5.0, and Java 8

<VirtualHost *:443>
    ...
    SSLEngine on
    SSLCertificateFile      /path/to/signed_certificate_followed_by_intermediate_certs
    SSLCertificateKeyFile   /path/to/private/key

    # Uncomment the following directive when using client certificate authentication
    #SSLCACertificateFile    /path/to/ca_certs_for_client_authentication


    # HSTS (mod_headers is required) (15768000 seconds = 6 months)
    Header always set Strict-Transport-Security "max-age=15768000"
    ...
</VirtualHost>

# modern configuration, tweak to your needs
SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite          ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
SSLHonorCipherOrder     on
SSLCompression          off
SSLSessionTickets       off

# OCSP Stapling, only in httpd 2.3.3 and later
SSLUseStapling          on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache        shmcb:/var/run/ocsp(128000)

nginx 1.10.1 | modern profile | OpenSSL 1.0.1e

Oldest compatible clients: Firefox 27, Chrome 30, IE 11 on Windows 7, Edge, Opera 17, Safari 9, Android 5.0, and Java 8

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /path/to/signed_cert_plus_intermediates;
    ssl_certificate_key /path/to/private_key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;


    # modern configuration. tweak to your needs.
    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    ## verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;

    resolver <IP DNS resolver>;

    ....
}

Quelle: https://mozilla.github.io/server-side-tls/ssl-config-generator/

SSL Webserver Test

Qualys hat eine tolle SSL Analyse Webseite, Link: https://www.ssllabs.com/ssltest/

Beispiel google.de:

Es zeigt einen schnellen Überblick plus sehr detailierte Informationen was nicht passt oder was man verbessern kann.

Alternative check with nmap

max@cmkdevel:~$ nmap --script ssl-cert,ssl-enum-ciphers -p 443 www.google.de            

Starting Nmap 7.01 ( https://nmap.org ) at 2017-08-01 09:08 CEST
Nmap scan report for www.google.de (172.217.17.35)
Host is up (0.031s latency).
Other addresses for www.google.de (not scanned): 2a00:1450:400e:804::2003
rDNS record for 172.217.17.35: ams16s29-in-f3.1e100.net
PORT    STATE SERVICE
443/tcp open  https
| ssl-cert: Subject: commonName=www.google.de/organizationName=Google Inc/stateOrProvinceName=California/countryName=US
| Issuer: commonName=Google Internet Authority G2/organizationName=Google Inc/countryName=US
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2017-07-19T11:48:30
| Not valid after:  2017-10-11T11:31:00
| MD5:   f21e dd1d 579f 5ea3 1b3d 2e79 873d 616c
|_SHA-1: f2af ac3f fb43 20be 9f6a b0fc 9356 808a f677 86fc
| ssl-enum-ciphers: 
|   TLSv1.0: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|     compressors: 
|       NULL
|     cipher preference: server
|   TLSv1.1: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|     compressors: 
|       NULL
|     cipher preference: server
|   TLSv1.2: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|     compressors: 
|       NULL
|     cipher preference: server
|_  least strength: C

Nmap done: 1 IP address (1 host up) scanned in 3.31 seconds

Postfix

/etc/postfix/main.cf

smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
smtpd_tls_mandatory_ciphers=high

tls_high_cipherlist=EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA

smtpd_tls_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, aECDH, EDH-DSS-DES-CBC3-SHA, EDH-RSA-DES-CBC3-SHA, KRB5-DES, CBC3-SHA

smtpd_tls_dh1024_param_file=/etc/ssl/dh2048.pem

smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
smtp_tls_protocols = !SSLv2, !SSLv3

lmtp_tls_mandatory_protocols = !SSLv2, !SSLv3
lmtp_tls_protocols = !SSLv2, !SSLv3

smtp_tls_security_level = may
smtp_tls_loglevel = 1

smtpd_tls_auth_only = yes

Generate new Diffie Hellman Keys

openssl dhparam -out /etc/ssl/dh2048.pem 2048

Restart Postfix

service postfix restart

Mehr: http://www.postfix.org/TLS_README.html

Check Postfix SSL Configuration

Test mit openssl s_client

openssl s_client -starttls smtp -connect mailserver.example.org:25

Alternative mit nmap

nmap --script ssl-cert,ssl-enum-ciphers -p 993,995,25,587 -Pn mailserver.example.org

Dovecot

/etc/dovecot/conf.d/10-ssl.conf

ssl_cipher_list = EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4
#only for dovecot >=2.2.6, enforce the server cipher preference
ssl_prefer_server_ciphers = yes
#disable SSLv2 and SSLv3
ssl_protocols = !SSLv2 !SSLv3

Restart dovecot

service dovecot restart

Überprüfen mit openssl s_connect

openssl s_client -connect mailserver.example.org:993
openssl s_client -connect mailserver.example.org:995

Alternative mit nmap

nmap --script ssl-cert,ssl-enum-ciphers -p 993,995 -Pn mailserver.example.org

SSH

/etc/ssh/sshd_config

# Remove dsa hostkeys
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key

KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr
Macs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256

AuthenticationMethods publickey
LogLevel VERBOSE
Subsystem sftp  /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO
PermitRootLogin No
UsePrivilegeSeparation sandbox

Achtung ! DSA SSH Keys werden danach nicht mehr funktionieren.

Quelle: https://github.com/mozilla/wikimo_content/blob/master/Security/Guidelines/OpenSSH.mediawiki#Modern_OpenSSH_67

Restart SSH

service ssh restart

OpenVPN

/etc/openvpn/openvpn.conf

tls-version-min 1.2
tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384
cipher AES-256-CBC
auth SHA512
reneg-sec 60

Quelle: https://community.openvpn.net/openvpn/wiki/Hardening / https://gist.github.com/pwnsdx/8fc14ee1e9f561a0a5b8

Patch für automysqlbackup: mysqldump: [Warning] Using a password on the command line interface can be insecure.

In der aktuellen Version von automysqlbackup kommt es auf Ubuntu 16.04 LTS wieder zu der Fehlermeldung:

mysqldump: [Warning] Using a password on the command line interface can be insecure.

Es gab vor einiger Zeit bereits einen Patch für das Problem allerdings hat sich der Code geändert dementsprechend waren anpassungen nötig. Orginalpatch zu finden unter: http://wiki.nkosi.org/Automysqlbackup / https://www.redeo.nl/2013/11/automysqlbackup-warning-using-password-command-line-interface-can-insecure/

Hier die neue angepasste Version für automysqlbackup v.2.5:

# Einfügen ab Zeile 644 vor if [ "$MAILCONTENT" = "files" ]

# Patch error message since MySQL 5.6
if [ -s "$LOGERR" ]
then

XLOGERR=$BACKUPDIR/XERRORS_$DBHOST-`date +%N`.log
grep -v "Using a password on the command line interface can be insecure." "$LOGERR" > $XLOGERR
mv $XLOGERR $LOGERR
fi

Patchfile

Ich habe auch ein Patchfile bereitgestellt, einfacher als im Code zu suchen.

Achtung! Patchfile ist für eine Standardinstallation auf einem Ubuntu 16.04 LTS, evtl. passt der Patch nicht wenn das File von einer anderen Distribution erstellt wurde, dann lieber manuell obigen Patch einfügen.
max@cmkdevel:~$ cp /usr/sbin/automysqlbackup automysqlbackup.backup
max@cmkdevel:~$ sudo patch /usr/sbin/automysqlbackup automysqlbackup.patch

Unattended Installation von APT Paketen (Debian/Ubuntu)

Um Pakete ohne manuelle Eingaben zu Installieren müssen die Antworten für die Assistenten bereits vorliegen.

Als Beispiel eine unattended Installation von Postfix auf einem Ubuntu 16.04 LTS System.

Um die möglichen Parameter zu erfahren verwendet man das „debconf-show“ Tool, Postfix muss auf dem Testsystem bereits installiert sein.

max@cmkdevel:/opt$ sudo debconf-show postfix
  postfix/procmail: false
  postfix/chattr: false
  postfix/recipient_delim: +
  postfix/sqlite_warning:
  postfix/dynamicmaps_conversion_warning:
  postfix/mydomain_warning:
  postfix/relayhost:
  postfix/compat_conversion_warning: true
  postfix/not_configured:
  postfix/rfc1035_violation: false
  postfix/root_address:
  postfix/protocols: all
  postfix/destinations: $myhostname, cmkdevel.m.local, localhost.m.local, , localhost
  postfix/kernel_version_warning:
  postfix/relay_restrictions_warning:
  postfix/mynetworks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
  postfix/mailbox_limit: 0
  postfix/tlsmgr_upgrade_warning:
* postfix/mailname: cmkdevel.m.local
* postfix/main_mailer_type: Internet Site
  postfix/bad_recipient_delimiter:
  postfix/main_cf_conversion_warning: true
  postfix/retry_upgrade_warning:

Um für ein neues System jetzt die Antworten dem Assistenten zu übergeben verwendet man das Tool „debconf-set-selections“. Der Kommandostapel setzt alle Optionen und Installiert automatisch Postfix.

debconf-set-selections <<< "postfix postfix/main_cf_conversion_warning string true"
debconf-set-selections <<< "postfix postfix/destinations string \$myhostname, $(hostname), localhost"
debconf-set-selections <<< "postfix postfix/root_address string max@m.local"
debconf-set-selections <<< "postfix postfix/bad_recipient_delimiter string ''"
debconf-set-selections <<< "postfix postfix/mynetworks string 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128"
debconf-set-selections <<< "postfix postfix/recipient_delim string +"
debconf-set-selections <<< "postfix postfix/protocols string all"
debconf-set-selections <<< "postfix postfix/relayhost string mail.example.org"
debconf-set-selections <<< "postfix postfix/mailname string $(hostname)"
debconf-set-selections <<< "postfix postfix/mailbox_limit string 0"
debconf-set-selections <<< "postfix postfix/chattr string false"
debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Satellite system'"
apt-get install -y postfix

Viel Spaß 😉

Postfix: Mail-Relay mit SMTP-Auth via Submission/TLS für ausgehende Mails

Ein Server soll als Relayhost (oder in der Windowswelt auch Smarthost gennant) dienen. Wer keine feste IP Adresse mit passenden DNS Reverse Eintrag hat wird schlechte Chancen haben das ein richtig konfigurierter Mailserver die Mails annehmen wird. Die Lösung ist die Mails an einen anderen Relayhost oder Mailserver zu schicken und dieser stellt dann die Mails zu. Manchmal bieten die Provider selbst Relayhosts an in vielen Fällen bleibt nichts anderes übrig als das ganze über ein Postfach zu versenden. Einige Provider bieten das Anliefern von Mails nur noch über Submission (TCP/587) und TLS verschlüsselt an. Ist mir persönlich auch lieber …

Beispielszenario

Provider: example.net

Mailaccount: user1@example.net Password: example%1

Mailserver: mail.example.net

Submission (TCP/587) und TLS sind notwendig.

 Lösung

„/etc/postfix/main.cf“ ergänzen mit:

relayhost = mail.example.net:submission
smtp_use_tls=yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/smtp_auth
smtp_sasl_security_options = noanonymous, noplaintext
smtp_sasl_tls_security_options = noanonymous

/etc/postfix/smtp_auth (Map-Datei, muss initialisiert werden!!!)

mail.example.net:submission               user1@example.net:example%1

Folgende Kommandos sind noch auszuführen:

postmap /etc/postfix/smtp_auth

durchführen um die Datei zu mappen.

/etc/init.d/postfix restart

durchführen um die Änderungen zu aktivieren.

socat: Pfiffiges Tool zum Mappen von IPv6 auf IPv4 Adressen

Wer gerade vor dem Problem steht alle Dienste auf seinen Linux Maschinen IPv4/IPv6 Dualstack fähig zu machen, der ist froh wenn er so ein Tool wie socat findet.

Es sind zwar die meisten Linux Dienste bereits Dualstack fähig aber es gibt vereinzelt noch Dienste wo keine regelmäßige bis keine Pflege der Software stattfindet.

socat ist quasi ein IPv6 -> IPv4 Relay. Das Paket ist im Packet Repository von Debian / Ubuntu verfügbar.

Beschreibung von socat aus der README des Pakets:

socat is a relay for bidirectional data transfer between two independent data
channels. Each of these data channels may be a file, pipe, device (serial line
etc. or a pseudo terminal), a socket (UNIX, IP4, IP6 - raw, UDP, TCP), an
SSL socket, proxy CONNECT connection, a file descriptor (stdin etc.), the GNU
line editor (readline), a program, or a combination of two of these.
These modes include generation of "listening" sockets, named pipes, and pseudo
terminals.

socat can be used, e.g., as TCP port forwarder (one-shot or daemon), as an
external socksifier, for attacking weak firewalls, as a shell interface to UNIX
sockets, IP6 relay, for redirecting TCP oriented programs to a serial line, to
logically connect serial lines on different computers, or to establish a
relatively secure environment (su and chroot) for running client or server
shell scripts with network connections.

Many options are available to refine socats behaviour:
terminal parameters, open() options, file permissions, file and process owners,
basic socket options like bind address, advanced socket options like IP source
routing, linger, TTL, TOS (type of service), or TCP performance tuning.

More capabilities, like daemon mode with forking, client address check,
"tail -f" mode, some stream data processing (line terminator conversion),
choosing sockets, pipes, or ptys for interprocess communication, debug and
trace options, logging to syslog, stderr or file, and last but not least
precise error messages make it a versatile tool for many different purposes.

In fact, many of these features already exist in specialized tools; but until
now, there does not seem to exists another tool that provides such a generic,
flexible, simple and almost comprehensive (UNIX) byte stream connector.

Das Tool kann noch wesentlich mehr, Infos findet man auf der Webseite des Programmierers http://www.dest-unreach.org/socat/.

Ich habe das für meinen alten SKS Keyserver verwendet, der noch kein IPv6 beherrscht. Ich lasse das ganze in einzelnen Screens laufen.

screen -dmS socat1 socat TCP6-LISTEN:11370,ipv6only=1,reuseaddr,fork TCP4:1.2.3.4:11370
screen -dmS socat2 socat TCP6-LISTEN:11371,ipv6only=1,reuseaddr,fork TCP4:1.2.3.4:11371
screen -dmS socat3 socat TCP6-LISTEN:80,ipv6only=1,reuseaddr,fork TCP4:1.2.3.4:11371

Damit das ganze auch noch einen Neustart überlebt kann man es noch in die /etc/rc.local vor dem „exit 0“ einfügen.

Python Version von getadsmtp.pl

Übersetzung des AD Mailadressen Sammelskripts von Perl nach Python.

#!/usr/bin/python

# getadsmtp.py
# Version 1.0
# The script is an translation from the orginal perl script getadsmtp.pl

# This script will pull all users' SMTP addresses from your Active Directory
# (including primary and secondary email addresses) and list them in the
# format "user@example.com OK" which Postfix uses with relay_recipient_maps.
# Be sure to double-check the path to python above.

# This requires python-ldap to be installed.  To install python-ldap on debian based systems,
# at a shell type "apt-get install python-ldap" or "sudo apt-get install python-ldap"

import os, sys, ldap

# Enter the path/file for the output
valid_addresses = "/etc/postfix/example_recipients"

# Enter the FQDN of your Active Directory domain controllers below
dc1="dc01.example.com"
dc2="dc02.example.com"

# Enter the LDAP container for your userbase.
# The syntax is CN=Users,dc=example,dc=com
# This can be found by installing the Windows 2000 Support Tools
# then running ADSI Edit.
# In ADSI Edit, expand the "Domain NC [domaincontroller1.example.com]" &amp;
# you will see, for example, DC=example,DC=com (this is your base).
# The Users Container will be specified in the right pane as
# CN=Users depending on your schema (this is your container).
# You can double-check this by clicking "Properties" of your user
# folder in ADSI Edit and examining the "Path" value, such as:
# LDAP://domaincontroller1.example.com/CN=Users,DC=example,DC=com
# which would be hqbase="cn=Users,dc=example,dc=com"
# Note:  You can also use just hqbase="dc=example,dc=com"
hqbase="cn=Users,dc=example,dc=com"

# Enter the username &amp; password for a valid user in your Active Directory
# with username in the form cn=username,cn=Users,dc=example,dc=com
# Make sure the user's password does not expire.  Note that this user
# does not require any special privileges.
# You can double-check this by clicking "Properties" of your user in
# ADSI Edit and examining the "Path" value, such as:
# LDAP://domaincontroller1.example.com/CN=user,CN=Users,DC=example,DC=com
# which would be $user="cn=user,cn=Users,dc=example,dc=com"
# Note: You can also use the UPN login: "user@example.com"
user="cn=user,cn=Users,dc=example,dc=com"
passwd="password"

try:
  l = ldap.initialize("ldap://%s" %(dc1))
  l.set_option(ldap.OPT_REFERRALS, 0)
  l.protocol_version = 3
  l.simple_bind_s(user, passwd)

except ldap.LDAPError, e:
  try:
    l = ldap.initialize("ldap://%s" %(dc2))
    l.set_option(ldap.OPT_REFERRALS, 0)
    l.protocol_version = 3
    l.simple_bind_s(user, passwd)

  except ldap.LDAPError, e:
    print "Error connecting to specified domain controllers\n"
    sys.exit()

# Play around with this to grab objects such as Contacts, Public Folders, etc.
# A minimal filter for just users with email would be:
# filter = "(&amp;(sAMAccountName=*)(mail=*))"
filter = "(&amp; (mailnickname=*) (| (&amp;(objectCategory=person)(objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*)))(&amp;(objectCategory=person)(objectClass=user)(|(homeMDB=*)(msExchHomeServerName=*)))(&amp;(objectCategory=person)(objectClass=contact))(objectCategory=group)(objectCategory=publicFolder)(objectClass=msExchDynamicDistributionList) ))"

attrs = ["proxyAddresses"]
scope = ldap.SCOPE_SUBTREE

r = l.search(hqbase, scope, filter, attrs)
type,a = l.result(r)
result_set = []

for x in a:
  name,attrs = x
  if hasattr(attrs, 'has_key') and attrs.has_key('proxyAddresses'):
    proxyAddresses = attrs['proxyAddresses']
    for y in proxyAddresses:
      result_set.append("%s OK" %(y.replace("smtp:","").replace("SMTP:","")))

# Add additional restrictions, users, etc. to the output file below.
#result_set.append("user@example.com OK")
#result_set.append("user1@example.com 550 User unknown.")
#result_set.append("bad.example.com 550 User does not exist.")

#######################################################################
# Build file ...
output = file(valid_addresses,'w')

for line in result_set:
  output.write("%s\n" %(line))

output.close()

 

Layer 3 VPN mit OpenSSH

OpenSSH ist in der Lage über Tun-Interfaces ein Layer 3 VPN herzustellen. Dies ist eine sehr einfache Variante, besonders schön ist das man SSH auch in vielen Fällen über einen Proxy verwenden kann.

Szenario

Aufbau:

  • Firewall (intern: 10.10.0.254, extern: 55.66.77.88, macht PAT über externes Interface)
  • SSHVPN VM ist eine VMware Maschine auf meinem VMware Server (intern: 10.10.0.122, tun0: 10.255.255.1, macht PAT über internes Interface)
  • Mein PC (Ubuntu 10.10 Maschine mit NX intern: 10.10.0.80)
  • Mein Netbook in dem Beispiel irgendwo im Internet mit UMTS Stick (Ubuntu 10.10 Netbook Edition)
  • Auf der Firewall ist ein NAT Portforwarding für TCP Port 22 auf 10.10.0.122 eingerichtet

Der Client

Falls noch kein Schlüsselpaar für root existiert muss eines angelegt werden.

toor@sshvpn-vm:~$ sudo ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/root/.ssh/id_rsa.
Your public key has been saved in /home/root/.ssh/id_rsa.pub.
The key fingerprint is:
05:d2:94:2e:16:fd:96:29:5c:6d:13:b5:55:8f:ce:31 root@sshvpn-vm
The key's randomart image is:
+--[ RSA 2048]----+
|      .+o. ..o. +|
|      ..+.. +  +.|
|       + o.+ .E .|
|      o +.=  o o |
|     . .So    o  |
|                 |
|                 |
|                 |
|                 |
+-----------------+
toor@sshvpn-vm:~$

Am einfachsten ist es ohne Passwort. Meine Empfehlung: Unbedingt mit Passwort machen, ist sicherer 😉 Den Namen unverändert lassen, auch den Speicherort. id_rsa wird im .ssh Verzeichnis beim Verbindungsaufbau vom ssh Client automatisch verwendet sofern vorhanden.

Anpassen der /etc/network/interfaces Datei

Folgenden Absatz an das Ende der Datei anfügen.

iface tun0 inet static
      pre-up ssh -S /var/run/sshvpn-tun-ctrl -M -f -w 0:0 55.66.77.88 true
      pre-up sleep 5
      address 10.255.255.2
      pointopoint 10.255.255.1
      netmask 255.255.255.252
      up route add -net 10.10.0.0 netmask 255.255.255.0 gw 10.255.255.1 tun0
      post-down ssh -S /var/run/sshvpn-tun-ctrl -O exit 55.66.77.88

Der Server

Anpassen der /etc/ssh/sshd_config Datei

Hinzufügen / Anpassen folgender Optionen

PermitTunnel point-to-point
PermitRootLogin forced-commands-only

PermitRootLogin existiert bei Ubuntu Systemen (steht auf Yes) schon bei anderen Distris kann das anders sein. Falls die PermitRootLogin existiert die orginale einfach auskommentieren.

Anpassen der /root/.ssh/authorized_keys Datei

tunnel="0",command="/sbin/ifdown tun0;/sbin/ifup tun0" ssh-rsa AAAA.... root@sshvpn-vm

Ab ssh-rsa muss alles ersetzt werden durch den Inhalt aus dem generierten öffentlichen Schüssel vom Client. (/root/.ssh/id_rsa.pub)

Anpassen der /etc/network/interfaces Datei

Folgenden Absatz an das Ende der Datei anfügen.

iface tun0 inet static
      address 10.255.255.1
      netmask 255.255.255.252
      pointopoint 10.255.255.2

IP Forwarding auf dem Server aktivieren

$ sysctl -w net.ipv4.ip_forward=1

Für eine dauerhaftes IP Forwarding muss mann noch die /etc/sysctl.conf anpassen.

echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf

NAT aktivieren

Ich habe auf meinem SSHVPN Server NAT aktiviert damit ich ohne Routing arbeiten kann, das ist einfacher.

Folgendes Script in /etc/init.d anlegen.

iptables.nat.sshvpn:

/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Aktivieren für Systemstart:

$  update-rc.d iptables.nat.sshvpn defaults

Test des VPN Tunnels

Auf dem Client kann der Tunnel mit folgendem Kommando gestartet werden.

$ sudo ifup tun0

Der SSH Client baut dann die Verbindung zum Server auf und richtet das Tunnelinterface ein.

Ein einfacher Ping zeigt das es funktioniert hat.

$  ping 10.10.0.80
PING 10.10.0.80 (10.10.0.80) 56(84) bytes of data.
64 bytes from 10.10.0.80: icmp_req=1 ttl=64 time=99.57 ms
64 bytes from 10.10.0.800: icmp_req=2 ttl=64 time=90.238 ms
64 bytes from 10.10.0.80: icmp_req=3 ttl=64 time=90.217 ms
64 bytes from 10.10.0.80: icmp_req=4 ttl=64 time=90.181 ms

Viel Spaß mit euren eigenen SSH VPNs 😉

Automatische Proxy Zuweisung über WPAD/PAC

In meiner Testumgebung verwende ich verschiedene Domains die nicht über einen Proxy gehen sollen. Da die manuelle Pflege an meinen Maschinen mir zu umständlich erscheint habe ich mich für den Proxy PAC (Proxy Auto Configuration) weg entschieden. Normalerweise wäre es ja ganz einfach, einfach bei jeder Domain als TLD .local verwenden und als Filter in der  Proxykonfiguration *.local ausschließen. Leider habe ich aber auch .com, usw. im Einsatz und ein Filter auf *.com wäre denkbar unpraktisch 😉 Die Lösung: PAC-File zentral auf meinem Server und bekanntgabe via WPAD.

PAC-File (wpad.dat)

function FindProxyForURL(url, host) {

   var proxy_yes = "PROXY proxy.lanbugs.local:3128";
   var proxy_wlan_yes = "PROXY proxy-wlan.lanbugs.local:3128";
   var proxy_no = "DIRECT";
   var proxy_failback = "PROXY proxy.lanbugs.local:3128; DIRECT";

   // Muss ins Internet direkt
   if (shExpMatch(url,"www.lanbugs.de/*")) {return proxy_yes;}
   if (shExpMatch(url,"www.thoma.cc/*")) {return proxy_yes;}

   // Interne Webseiten
   if (shExpMatch(url,"*.lanbugs.local/*")) {return proxy_no;}
   if (shExpMatch(url, "*.lanbugs.de/*")) {return proxy_no;}
   if (shExpMatch(url, "*.thoma.cc/*")) {return proxy_no;}

   // Homenet
   if (isInNet(host, "10.10.4.0", "255.255.255.0")) {
      return proxy_yes;
   }

   // WLAN
   if (isInNet(host, "10.10.5.0", "255.255.255.0")) {
      return proxy_wlan_yes;
   }

   // Server
   if (isInNet(host, "10.10.4.200", "255.255.255.255"){
     return proxy_no;
   }

   return proxy_failback;
}

Meine PAC Konfiguration mancht folgendes:

  • www.lanbugs.de wird weiterhin zum Proxy gesendet alles andere wird direkt über den internen DNS auf interne Webserver umgeleitet
  • www.thoma.cc wird weiterhin zum Proxy gesendet alles andere wird direkt über den internen DNS aus interne Webserver umgeleitet
  • *.lanbugs.local wird komplett vom Proxy ausgeschlossen
  • Mein Homenet wird komplett über den Proxy proxy.lanbugs.local abgewickelt
  • Mein WLAN Netz wird komplett über den Proxy proxy-wlan.lanbugs.local abgewickelt
  • Für den Server 10.10.4.200 geht nicht über den Proxy
  • Für alle anderen wird versucht über den Proxy zu gehen funktioniert das nicht versucht der Browser es direkt

WPAD Konfiguration

WPAD lässt sich über DNS, DHCP und als manuelles File verteilen, leider unterstützen nicht alle Browser alle Wege.

WPAD Kompatibilitätsliste

Browser DNS DHCP Manuelles File
Internet Explorer 6.0 (SP1) und höher JA JA JA
Firefox 1.5.x JA NEIN JA
Firefox 2.5.x JA NEIN JA
Opera NEIN NEIN JA
NetScape JA NEIN JA
Safari ? ? JA

Vorbereiten des Webservers für WPAD/PAC File

Mein Server läuft mit Ubuntu 8.04 LTS. Bei den Ubuntu / Debian Versionen liegt die MIME Type Konfiguration unter /etc/apache2/mods-enabled.

/etc/apache2/mods-enabled/mime.conf

AddType application/x-ns-proxy-autoconfig .dat
AddType application/x-ns-proxy-autoconfig .pac

Desweiteren sollte die Dateiendung noch in /etc/mime.types bekannt gegeben werden.

application/x-ns-proxy-autoconfig dat
application/x-ns-proxy-autoconfig pac

Das PAC File liegt im root-Verzeichnis des Webservers /var/www als proxy.pac und wpad.dat. Alternativ habe ich noch einen Vorschlag gelesen nur die proxy.pac anzulegen und die Datei via redirect unter wpad.dat erreichbar zu machen. Geschmackssache ….

WPAD via DNS

WPAD via DNS geht über verschiedene Wege. Entweder über einen A/CNAME Record oder über einen TXT/SRV Eintrag. Es kann nicht schaden alle möglichkeiten anzulegen. Per DHCP wird in meinem Netz die Domain lanbugs.local als Primäres DNS Suffix mitgegeben, folglich muss ein Eintrag für wpad.lanbugs.local angelegt werden.

Auszug aus der Zone lanbugs.local:

...
wpad           IN A                       10.10.4.200
wpad.tcp       IN SRV       0 0 80        10.10.4.200
               IN TXT                     "service: wpad:http://wpad.lanbugs.local/wpad.dat"
...

WPAD via DHCP

Der DHCP Server muss mit der Option 252 erweitert werden. In dieser Option wird die URL der wpad.dat eingefügt.

option wpad code 252 = text;

subnet 10.10.4.0 netmask 255.255.255.0 {
…
option wpad “http://wpad.lanbugs.local/wpad.dat ”;
…
}

subnet 10.10.5.0 netmask 255.255.255.0 {
…
option wpad “http://wpad.lanbugs.local/wpad.dat ”;
…
}

WPAD via Manuelles File

Falls alles nicht funktionieren  sollte lässt sich das File auch manuell Eintragen.

Firefox:

Extras -> Einstellungen -> Erweitert -> Netzwerk -> Verbindung (Einstellungen) -> Automatische Proxy-Konfigurations-URL: http://wpad.lanbugs.local/proxy.pac

Internet Explorer:

Extras -> Internet Optionen -> Verindungen -> LAN-Einstellungen (Einstellungen) -> (x) Automatisches Konfigurationsskript verwenden: http://wpad.lanbugs.local/proxy.pac

Chrome:

Nutzt die Einstellungen vom Internet Explorer

Opera:

Einstellungen -> Netzwerk -> Proxyserver -> (x) Automatische Proxykonfiguration verwenden (Skript): http://wpad.lanbugs.local/proxy.pac

Finale

Damit die automatische Zuweisung klappt sollte der Browser auch so eingestellt sein das er eine WPAD Konfiguration zulässt.

Firefox:

Extras -> Einstellungen -> Erweitert -> Netzwerk -> Verbindung (Einstellungen) -> (x) Die Proxy-Einstellungen für dieses Netzwerk automatisch erkennen

Internet Explorer:

Extras -> Internet Optionen -> Verindungen -> LAN-Einstellungen (Einstellungen) -> (x) Automatische Suche der Einstellungen

Chrome:

Nutzt die Einstellugen vom Internet Explorer

Opera:

Hier scheint nur der manuelle Weg zu bleiben

Postfix als Frontend für einen Microsoft Exchange Server

Für einen Kunden habe ich einen Postfix eingerichtet als Frontend Server für seine Exchange Infrastruktur. Die Mailadressen werden automatisch aus dem Active Directory ausgelesen und in einem Hash-File gespeichert. Vorteil ist das der Postfix so nur gültige Mailaliases zulässt. Der Frontend macht auch noch weitere Überprüfungen. (postgrey, policy-weight, etc.)

Folgendes Script wird für das Auslesen der Aliase aus dem AD verwendet:

#!/usr/bin/perl -T -w

# Version 1.02

# This script will pull all users' SMTP addresses from your Active Directory
# (including primary and secondary email addresses) and list them in the
# format "user@example.com OK" which Postfix uses with relay_recipient_maps.
# Be sure to double-check the path to perl above.

# This requires Net::LDAP to be installed.  To install Net::LDAP, at a shell
# type "perl -MCPAN -e shell" and then "install Net::LDAP"

use Net::LDAP;
use Net::LDAP::Control::Paged;
use Net::LDAP::Constant ( "LDAP_CONTROL_PAGED" );

# Enter the path/file for the output
$VALID = "/etc/postfix/example_recipients";

# Enter the FQDN of your Active Directory domain controllers below
$dc1="domaincontroller1.example.com";
$dc2="domaincontroller2.example.com";

# Enter the LDAP container for your userbase.
# The syntax is CN=Users,dc=example,dc=com
# This can be found by installing the Windows 2000 Support Tools
# then running ADSI Edit.
# In ADSI Edit, expand the "Domain NC [domaincontroller1.example.com]" &
# you will see, for example, DC=example,DC=com (this is your base).
# The Users Container will be specified in the right pane as
# CN=Users depending on your schema (this is your container).
# You can double-check this by clicking "Properties" of your user
# folder in ADSI Edit and examining the "Path" value, such as:
# LDAP://domaincontroller1.example.com/CN=Users,DC=example,DC=com
# which would be $hqbase="cn=Users,dc=example,dc=com"
# Note:  You can also use just $hqbase="dc=example,dc=com"
$hqbase="cn=Users,dc=example,dc=com";

# Enter the username & password for a valid user in your Active Directory
# with username in the form cn=username,cn=Users,dc=example,dc=com
# Make sure the user's password does not expire.  Note that this user
# does not require any special privileges.
# You can double-check this by clicking "Properties" of your user in
# ADSI Edit and examining the "Path" value, such as:
# LDAP://domaincontroller1.example.com/CN=user,CN=Users,DC=example,DC=com
# which would be $user="cn=user,cn=Users,dc=example,dc=com"
# Note: You can also use the UPN login: "user\@example.com"
$user="cn=user,cn=Users,dc=example,dc=com";
$passwd="password";

# Connecting to Active Directory domain controllers
$noldapserver=0;
$ldap = Net::LDAP->new($dc1) or
   $noldapserver=1;
if ($noldapserver == 1)  {
   $ldap = Net::LDAP->new($dc2) or
      die "Error connecting to specified domain controllers $@ \n";
}

$mesg = $ldap->bind ( dn => $user,
                     password =>$passwd);
if ( $mesg->code()) {
    die ("error:", $mesg->code(),"\n","error name: ",$mesg->error_name(),
        "\n", "error text: ",$mesg->error_text(),"\n");
}

# How many LDAP query results to grab for each paged round
# Set to under 1000 for Active Directory
$page = Net::LDAP::Control::Paged->new( size => 990 );

@args = ( base     => $hqbase,
# Play around with this to grab objects such as Contacts, Public Folders, etc.
# A minimal filter for just users with email would be:
# filter => "(&(sAMAccountName=*)(mail=*))"
         filter => "(& (mailnickname=*) (| (&(objectCategory=person)
                    (objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*)))
                    (&(objectCategory=person)(objectClass=user)(|(homeMDB=*)
                    (msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=contact))
                    (objectCategory=group)(objectCategory=publicFolder)(objectClass=msExchDynamicDistributionList) ))",
          control  => [ $page ],
          attrs  => "proxyAddresses",
);

my $cookie;
while(1) {
  # Perform search
  my $mesg = $ldap->search( @args );

# Filtering results for proxyAddresses attributes
  foreach my $entry ( $mesg->entries ) {
    my $name = $entry->get_value( "cn" );
    # LDAP Attributes are multi-valued, so we have to print each one.
    foreach my $mail ( $entry->get_value( "proxyAddresses" ) ) {
     # Test if the Line starts with one of the following lines:
     # proxyAddresses: [smtp|SMTP]:
     # and also discard this starting string, so that $mail is only the
     # address without any other characters...
     if ( $mail =~ s/^(smtp|SMTP)://gs ) {
       push(@valid, $mail." OK\n");
     }
    }
  }

  # Only continue on LDAP_SUCCESS
  $mesg->code and last;

  # Get cookie from paged control
  my($resp)  = $mesg->control( LDAP_CONTROL_PAGED ) or last;
  $cookie    = $resp->cookie or last;

  # Set cookie in paged control
  $page->cookie($cookie);
}

if ($cookie) {
  # We had an abnormal exit, so let the server know we do not want any more
  $page->cookie($cookie);
  $page->size(0);
  $ldap->search( @args );
  # Also would be a good idea to die unhappily and inform OP at this point
     die("LDAP query unsuccessful");
}
# Only write the file once the query is successful
open VALID, ">$VALID" or die "CANNOT OPEN $VALID $!";
print VALID @valid;
# Add additional restrictions, users, etc. to the output file below.
#print VALID "user\@example.com OK\n";
#print VALID "user1\@example.com 550 User unknown.\n";
#print VALID "bad.example.com 550 User does not exist.\n";

close VALID;

Quelle: http://www-personal.umich.edu/~malth/gaptuning/postfix/

Ich habe das Perlscript in /etc/postfix abgelegt. Rechte sollten auch 700 sein. Diese 6 Parameter müssen geändert werden.

$VALID = "/etc/postfix/exchange_recipients";

$dc1="dc01.lanbugs.intra";
$dc2="dc02.lanbugs.intra";

$hqbase="cn=Users,dc=lanbugs,dc=intra";

$user="cn=sys-read-aliases-mailfront,cn=Users,dc=lanbugs,dc=intra";
$passwd="geheim123";

Das Script wird als Cronjob jede Stunde ausgeführt. Hierzu muss nur ein File mit dem Namen run_read_aliases_from_exchange.sh mit den Rechten 700 im Verzeichnis /etc/cron.hourly angelegt werden. (Debian/Ubuntu)

run_read_aliases_from_exchange.sh:

#!/bin/sh

cd /etc/postfix ; ./getadsmtp.pl && postmap exchange_recipients

In der /etc/postfix/main.cf kann dann das neue Hash-File als relay_recipient_map verwendet werden.

main.cf:

...
relay_recipient_maps = hash:/etc/postfix/exchange_recipients
relay_domains = lanbugs.de
transport_maps = hash:/etc/postfix/transport
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.1.1.20/32
...

relay_domains erlaubt allgemein die Domain lanbugs.de. mynetworks wurde noch um die IP-Adresse des Exchange Servers erweitert damit dieser E-Mails zur Außenwelt senden kann. Die transport_maps sorgen dafür dass alle Mails an lanbugs.de an den Exchange Server weiter transportiert werden.

/etc/postfix/transport: (nach dem Anlegen postmap /etc/postfix/transport nicht vergessen!!!!)

langbugs.de      smtp:[10.1.1.20]:25

10.1.1.20 ist der interne Exchange Server.

Viel Spaß mit dem Postfix Frontend 😉

Forwarding für bestimmte DNS Zonen in Bind9

In diesem Szenario hat der Kunde in der DMZ 2 DNS Server (Forwarding zum Provider) stehen. Diese DNS Server sind die „Inernet“ DNS Server. Im internen Netz betreibt der Kunde mehrere Active Directory instanzen. Der Kunde möchte das seine internen DNS Zonen innerhalb der DMZ auflösbar sind. Dies kann man über Zonenweiterleitung in Bind realisieren.

zone "ad01.local" IN {
	type forward;
	forwarders {10.0.0.1; 10.0.0.2;};
};

zone "ad02.local" IN {
	type forward;
	forwarders {10.0.0.3; 10.0.0.4;};
};

zone "msexch.local" IN {
	type forward;
	forwarders {10.0.0.5; 10.0.0.6;};
};

eth Inferfacenummerierung ändern

für Ubuntu / Debian

In bestimmten Fällen will man die Nummerierung der eth Interfaces ändern. Wenn z.B. eine virtuelle Maschine geklont wird und eine neue MAC-Adresse für das Ethernet Interface generiert wird dann würde das Interface eth1 lauten.

Die Zuordnung der Interfaces wird über UDEV realisiert in der Datei /etc/udev/rules.d/70-persistent-net.rules

Nach Änderung der MAC Adresse:

# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.


# PCI device 0x1022:0x2000 (pcnet32)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:15:a5:b6", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

# PCI device 0x1022:0x2000 (pcnet32)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:15:a5:b7", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

00:0c:29:15:a5:b7 soll wieder eth0 werden 00:0c:29:15:a5:b6 gibt es nicht mehr und kann gelöscht werden.

Nach Änderung:

# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.

# PCI device 0x1022:0x2000 (pcnet32)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:15:a5:b7", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

Neue SSH Hostkeys generieren

für Debian / Ubuntu

Falls man eine VMware Maschine kopiert benötigt man neue SSH Keys. Folgende Zeilen generieren neue Keys.

sudo rm /etc/ssh/ssh_host_key
sudo rm /etc/ssh/ssh_host_key.pub
sudo rm /etc/ssh/ssh_host_rsa_key
sudo rm /etc/ssh/ssh_host_rsa_key.pub
sudo rm /etc/ssh/ssh_host_dsa_key
sudo rm /etc/ssh/ssh_host_dsa_key.pub
sudo /usr/bin/ssh-keygen -t rsa1 -f /etc/ssh/ssh_host_key -N ""
sudo /usr/bin/ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ""
sudo /usr/bin/ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ""

WPA Enterprise mit EAP PEAP

Howto für Ubuntu und Debian

Für dieses Howto wird freeradius mit openssl Support benötigt.

Eine Anleitung für freeradius+openssl ist hier zu finden: Freeradius mit EAP Support

Die Pakete wie in der Anleitung beschrieben installieren.

Die unten aufgeführten Konfigurationsteile sind Ergänzungen oder Änderungen der Default Config.

openssl installieren
apt-get install openssl
RootCA anlegen

In das Verzeichnis /etc/freeradius/certs wechseln

cd /etc/freeradius/certs

openssl liefert ein einfaches Script um eine CA anzulegen.

/usr/lib/ssl/misc/CA.pl -newca
CA certificate filename (or enter to create)

Mit [Enter] bestätigen.

Making CA certificate ...
Generating a 1024 bit RSA private key
...............................................++++++
..........++++++
writing new private key to './demoCA/private/cakey.pem'

Ein Passwort definieren und eingeben.

Enter PEM pass phrase:
Verifying – Enter PEM pass phrase:

-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----

Country Name (2 letter code) [AU]:DE
State or Province Name (full name) [Some-State]:Bayern
Locality Name (eg, city) []:München
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Test
Organizational Unit Name (eg, section) []:Testabteilung
Common Name (eg, YOUR name) []:rootca
Email Address []:rootca@example.org

Please enter the following 'extra' attributes
to be sent with your certificate request

2 mal mit [Enter] bestätigen.

A challenge password []:
An optional company name []:

Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            b7:bc:7f:60:3c:98:84:b2
        Validity
            Not Before: Jul 31 07:33:47 2009 GMT
            Not After : Jul 30 07:33:47 2012 GMT
        Subject:
            countryName               = DE
            stateOrProvinceName       = Bayern
            organizationName          = Test
            organizationalUnitName    = Testabteilung
            commonName                = rootca
            emailAddress              = rootca@example.org
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                5C:85:A3:1C:70:8E:E3:60:62:C9:5A:60:83:A2:D5:3C:EA:64:C7:C9
            X509v3 Authority Key Identifier:
                keyid:5C:85:A3:1C:70:8E:E3:60:62:C9:5A:60:83:A2:D5:3C:EA:64:C7:C9
                DirName:/C=DE/ST=Bayern/O=Test/OU=Testabteilung/CN=rootca/emailAddress=rootca@example.org
                serial:B7:BC:7F:60:3C:98:84:B2

            X509v3 Basic Constraints:
                CA:TRUE
Certificate is to be certified until Jul 30 07:33:47 2012 GMT (1095 days)

Write out database with 1 new entries
Data Base Updated
Server Zertifikat erzeugen
openssl req -new -nodes -keyout server_key.pem -out server_req.pem -days 730 -config /etc/ssl/openssl.cnf
Generating a 1024 bit RSA private key
...++++++
..............................................................................++++++
writing new private key to 'server_key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----

Country Name (2 letter code) [AU]:DE
State or Province Name (full name) [Some-State]:Bayern
Locality Name (eg, city) []:München
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Test
Organizational Unit Name (eg, section) []:Testabteilung
Common Name (eg, YOUR name) []:server
Email Address []:server@example.org

Please enter the following 'extra' attributes
to be sent with your certificate request

A challenge password []:
An optional company name []:

Server Zertifikat mit der rootCA signieren
openssl ca -config /etc/ssl/openssl.cnf -policy policy_anything -out server_cert.pem -infiles ./server_req.pem
Using configuration from /etc/ssl/openssl.cnf

Passwort der CA eingeben:

Enter pass phrase for ./demoCA/private/cakey.pem:

Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            b7:bc:7f:60:3c:98:84:b3
        Validity
            Not Before: Jul 31 08:10:11 2009 GMT
            Not After : Jul 31 08:10:11 2010 GMT
        Subject:
            countryName               = DE
            stateOrProvinceName       = Bayern
            localityName              = M\C3\BCnchen
            organizationName          = Test
            organizationalUnitName    = Testabteilung
            commonName                = server
            emailAddress              = server@example.org
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                D7:95:A8:C4:D7:70:BE:4C:D4:52:B1:E6:B5:A6:CD:37:B2:4A:6B:AE
            X509v3 Authority Key Identifier:
                keyid:5C:85:A3:1C:70:8E:E3:60:62:C9:5A:60:83:A2:D5:3C:EA:64:C7:C9

Certificate is to be certified until Jul 31 08:10:11 2010 GMT (365 days)

Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y

Write out database with 1 new entries
Data Base Updated
Server Zertifikat zusammenbauen
cat server_key.pem server_cert.pem > server.pem
radiusd.conf
mschap {
 authtype = MS-CHAP
 use_mppe = yes
 require_encryption = yes
 require_strong = yes
clients.conf

In clients.conf muss für den Accesspoint ein „Shared Secret“ festgelegt werden. 192.168.0.10 ist die IP des Accesspoints.

client 192.168.0.10 {
        # This is the shared secret between the Authenticator (the
        # access point) and the Authentication Server (RADIUS).
        secret          = 123password456
        shortname       = accesspoint
    }
users

Einen neuen User anlegen. Am Ende der users Datei einen neuen Benutzer hinzufügen. ACHTUNG in mehreren Howtos wird der Syntax User-Password == „password“ noch verwendet. Dieser Syntax ist für freeradius Version 2.x obsolet. Der neue Syntax lautet Cleartext-Password := „password“.

"mobil-user"     Cleartext-Password := "password123"
eap.conf
eap {
 default_eap_type = peap
  tls {
   CA_file = ${cadir}/demoCA/cacert.pem
  }
}
sites-enabled/default
authorize {
 mschap
 # unix
}

authenticate {
 Auth-Type MS-CHAP {
  mschap
 }
 # unix
}

accounting {
 # unix
}
freeradius testen
freeradius -X

Wenn alles ohne Fehler durchläuft sollte da folgendes erscheinen

Listening on authentication address * port 1812
Listening on accounting address * port 1813
Listening on proxy address * port 1814
Ready to process requests.
Daemon starten
[Strg-C]
/etc/init.d/freeradius start
Accesspoint einstellen -Allgemein-
  • Radiusserver + Radiusport + Shared Secret eingeben
  • Modus: WPA2-Enterprise
Client anbinden -Allgemein-
  • CAcert.pem zu den vertrauten Zertifizierungsstellen hinzufügen
  • Mode WPA2-Enterprise
  • EAP PEAP auswählen
Fertig!

freeradius mit EAP TLS/TTLS/PEAP Support

Howto für Ubuntu und Debian

Das Paket wird leider bei Debian und Ubuntu ohne SSL Support ausgeliefert weshalb alle EAP Varianten die SSL benötigen nicht funktionieren. Das Paket kann aber relativ einfach selbst gebaut werden dank der Debiantools.

Benötigte Pakete
apt-get install build-essentials apt-src
Sourcen laden
cd ~
mkdir build_freeradius
cd build_freeradius
apt-src install freeradius
Änderungen
cd freeradius-2.0.4+dfsg/debian

File: rules

von

...
--without-rlm_eap_tls \
--without-rlm_eap_ttls \
--without-rlm_eap_peap \
...
--without-openssl \
...

auf

...
--with-rlm_eap_tls \
--with-rlm_eap_ttls \
--with-rlm_eap_peap \
...
--with-openssl \
...

und

for pkg in ${pkgs} ; do \
   if dh_shlibdeps -p $$pkg -- -O 2>/dev/null | grep -q libssl; then \
      echo "$$pkg links to openssl" ;\
      exit 1 ;\
   fi ;\
done

entfernen.

File: control

Am Ende der Teile „Build-Depends:“ libssl-dev anfügen.

Source: freeradius
Build-Depends: autotools-dev, debhelper (>= 6.0.7), libgdbm-dev, libiodbc2-dev, libkrb5-dev, libldap2-dev, libltdl3-dev, libmysqlclient15-dev | libmysqlclient-dev, libpam0g-dev, libpcap-dev, libperl-dev, libpq-dev, libsasl2-dev, libsnmp-dev, libtool, python-dev, libssl-dev
Verzeichnis debian verlassen und Paket bauen
cd ..
dpkg-buildpackage -rfakeroot
Pakete sind fertig
drwxr-xr-x 15 root root    4096 30. Jul 11:57 freeradius-2.0.4+dfsg
-rw-r--r--  1 root root    5351 30. Jul 11:54 freeradius_2.0.4+dfsg-6.diff.gz
-rw-r--r--  1 root root    1243 30. Jul 11:54 freeradius_2.0.4+dfsg-6.dsc
-rw-r--r--  1 root root    5382 30. Jul 11:58 freeradius_2.0.4+dfsg-6_i386.changes
-rw-r--r--  1 root root  504906 30. Jul 11:58 freeradius_2.0.4+dfsg-6_i386.deb
-rw-r--r--  1 root root 2953674 19. Mai 2008  freeradius_2.0.4+dfsg.orig.tar.gz
-rw-r--r--  1 root root  205830 30. Jul 11:58 freeradius-common_2.0.4+dfsg-6_all.deb
-rw-r--r--  1 root root  928204 30. Jul 11:58 freeradius-dbg_2.0.4+dfsg-6_i386.deb
-rw-r--r--  1 root root  132494 30. Jul 11:58 freeradius-dialupadmin_2.0.4+dfsg-6_all.deb
-rw-r--r--  1 root root   17190 30. Jul 11:58 freeradius-iodbc_2.0.4+dfsg-6_i386.deb
-rw-r--r--  1 root root   18090 30. Jul 11:58 freeradius-krb5_2.0.4+dfsg-6_i386.deb
-rw-r--r--  1 root root   34740 30. Jul 11:58 freeradius-ldap_2.0.4+dfsg-6_i386.deb
-rw-r--r--  1 root root   24996 30. Jul 11:58 freeradius-mysql_2.0.4+dfsg-6_i386.deb
-rw-r--r--  1 root root   35934 30. Jul 11:58 freeradius-postgresql_2.0.4+dfsg-6_i386.deb
-rw-r--r--  1 root root   71854 30. Jul 11:58 freeradius-utils_2.0.4+dfsg-6_i386.deb
-rw-r--r--  1 root root   85280 30. Jul 11:58 libfreeradius2_2.0.4+dfsg-6_i386.deb
-rw-r--r--  1 root root  104758 30. Jul 11:58 libfreeradius-dev_2.0.4+dfsg-6_i386.deb
Paket installieren
dpkg -i freeradius-common_2.0.4+dfsg-6_all.deb
dpkg -i libfreeradius2_2.0.4+dfsg-6_i386.deb
dpkg -i freeradius_2.0.4+dfsg-6_i386.deb
freeradius auf hold setzen

Damit beim nächsten apt-get upgrade unser selbstgebautes Paket nicht überschrieben wird müssen wir das Paket noch auf hold setzen.

dpkg --get-selections | grep free
freeradius					install
freeradius-common				install
libfreeradius2					install
dpkg --set-selections [enter]
freeradius hold
freeradius-common hold
libfreeradius2 hold
[Strg+D]

Ergebnis kontrollieren

dpkg --get-selections | grep free
freeradius					hold
freeradius-common				hold
libfreeradius2					hold
Fertig

TFTPd – Server

Howto für  Ubuntu und  Debian

Pakete installieren
sudo apt-get install xinetd tftpd tftp
Datei: /etc/xinetd.d/tftp anlegen
nano /etc/xinetd.d/tftp
service tftp
{
protocol        = udp
port            = 69
socket_type     = dgram
wait            = yes
user            = nobody
server          = /usr/sbin/in.tftpd
server_args     = /srv/tftp
disable         = no
}
Ordner anlegen
sudo mkdir /srv/tftp
sudo chmod -R 777 /srv/tftp
sudo chown -R nobody /srv/tftp
tftpd über xinetd starten
sudo /etc/init.d/xinetd start
Test

Testfile anlegen

root@test4:/root# dd bs=1000 count=5 if=/dev/urandom of=testfile.txt

root@test4:/root# ls -la testfile.txt
-rw-r--r-- 1 root root 5000 2009-07-22 19:49 testfile.txt

Verbinden mit TFTP Server und Datei übertragen

root@test4:/root# tftp 10.1.1.1
tftp> put testfile.txt
Sent 5000 bytes in 0.0 seconds
tftp> quit

In Serververzeichnis wecheln

cd /srv/tftp

File ist vollständig angekommen

root@test4:/srv/tftp# ls -la testfile.txt
-rw------- 1 nobody nogroup   5000 2009-07-22 19:50 testfile.txt
Fertig