Forum Linux.général Protection d'une application par NAT interne + Authentification Kerberos

Posté par  . Licence CC By‑SA.
0
31
mar.
2015

Bonjour tout le monde ! :)

Dans le cadre d'un projet durant mes études,
Je rencontre beaucoup de difficultés car je ne maîtrise pas suffisamment IPTables et Apache pour savoir d'où provient mon problème.

J'ai mis en place une application, dont l'interface est généré par Jetty, et accessible via navigateur sur le port 44440.

Il m'a été demandé de mettre en place une authentification avec Kerberos, afin de permettre une authentification qui sera basée sur l'AD de l'entreprise.
Le problème est que cette application ne possède rien pour faire ça.

Je suis donc parti sur l'idée suivante:
- Autoriser dans l'application la connexion uniquement depuis localhost.
- Configurer IPTables pour que les connexions arrivant sur le port 80 soit ensuite perçu comme de source "localhost" et qu'elles soient redirigés vers Apache (j'ai pris le port 44441, un peu au hasard je l'avoue).
- Configurer Apache pour qu'il fasse l'authentification Kerberos, et que si l'authentification est validée il redirige vers le port 44440 (mon application).

J'ai réalisé un schéma pour mieux illustrer ce que je veux faire :
Configuration

Mon problème, c'est que ça ne fonctionne pas et que j'arrive pas à identifier d'où proviennent les erreurs de fonctionnement. :(

Voici donc ma configuration IPTables:

# Generated by iptables-save v1.4.7 on Tue Mar 31 10:37:56 2015
*nat
-A PREROUTING -d IP_Serveur_LAN/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 127.0.0.1:44441 
-A POSTROUTING -d 127.0.0.1/32 -o lo -p tcp -m tcp --dport 44441 -j SNAT --to-source 127.0.0.1 
COMMIT

*filter
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT 
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT 
-A INPUT -i lo -p tcp -m tcp --dport 44441 -j Cid2023X8611.0 
-A INPUT -i eth0 -p tcp -m tcp --dport 59999 -j ACCEPT 
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT 
-A INPUT -s IP_Serveur_LAN/32 -i lo -j Cid2083X8611.0 
-A INPUT -s 127.0.0.1/32 -i lo -j Cid2083X8611.0 
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A FORWARD -j REJECT --reject-with icmp-host-prohibited 
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A OUTPUT -s IP_Serveur_LAN/32 -o lo -j Cid2083X8611.1 
-A OUTPUT -s 127.0.0.1/32 -o lo -j Cid2083X8611.1 
-A OUTPUT -j ACCEPT 
-A Cid2023X8611.0 -s IP_Serveur_LAN/32 -j Cid2023X8611.1 
-A Cid2023X8611.0 -s 127.0.0.1/32 -j Cid2023X8611.1 
-A Cid2023X8611.1 -d IP_Serveur_LAN/32 -j ACCEPT 
-A Cid2023X8611.1 -d 127.0.0.1/32 -j ACCEPT 
-A Cid2083X8611.0 -d IP_Serveur_LAN/32 -j ACCEPT 
-A Cid2083X8611.0 -d 127.0.0.1/32 -j ACCEPT 
-A Cid2083X8611.1 -d IP_Serveur_LAN/32 -j ACCEPT 
-A Cid2083X8611.1 -d 127.0.0.1/32 -j ACCEPT 
COMMIT

Etant donné que je n'avais pas l'impression d'y arriver avec IPTables, j'ai voulu utiliser fwbuilder, ça m'a donc généré Cid2023X8611.0 et Cid2023X8611.1, qui je suppose sont eth0 et lo.
fwbuilder

Pour la configuration Apache2 (juste les parties concernant ma demande d'aide):

Listen 44441
ServerName IP_Serveur_LAN:44441

<Proxy http://IP_Serveur_LAN:*/*> 
AuthName "JOBSCHD Access"
AuthType Kerberos
Krb5Keytab  /etc/krb5.ktab
KrbAuthRealms EXEMPLE.PRIV
KrbMethodNegotiate On
KrbMethodK5Passwd On
require valid-user
</Proxy>
#
ProxyPass /:44441/ http://localhost:44440/jobscheduler/operations_gui/
ProxyPassReverse /:44441/ http://IP_Serveur_LAN:44440/jobscheduler/operations_gui

Voici ma configuration Kerberos, mais je pense qu'elle fonctionne car quand je fais kinit sur mon serveur, elle fonctionne bien:

[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 default_realm = EXEMPLE.PRIV
 dns_lookup_realm = false
 dns_lookup_kdc = false

[realms]
 EXEMPLE.PRIV = {
  kdc = nomServeurAD.exemple.priv:88
  admin_server = nomServeurAD.exemple.priv:749
  default_domain = exemple.priv 
}

[domain_realm]
 .exemple.priv = EXEMPLE.PRIV
 exemple.priv = EXEMPLE.PRIV

[appdefaults]
 pam = {
   debug = false
   ticket_lifetime = 36000
   renew_lifetime = 36000
   forwardable = true
   krb4_convert = false
 }

Voilà donc tous les éléments que j'utilise ci dessus.
Pourriez-vous m'aidez ou m'orienter sur ce qui ne va pas svp ?

Je ne suis encore qu'un jeune en alternance, donc je n'ai pas de très grosses compétences, mais je comprends plutôt vite et bien.
Je pensais arriver à résoudre mon problème seul, mais je commence à me prendre la pression car ça me bloque mon projet et l'année continue d'avancer, je me tourne donc vers ce forum pour vous demander de l'aide.

Merci pour votre lecture, et un gros merci pour ce qui prendront le temps de me répondre.

Je vous souhaite une très bonne journée à tous !

Guillaume.

  • # Simplification et vérification des logs

    Posté par  . Évalué à 4. Dernière modification le 31 mars 2015 à 13:13.

    La solution de mettre un mod_proxy est une bonne solution amha.
    Par contre, pourquoi différencier :

    ProxyPass /:44441/ http://localhost:44440/jobscheduler/operations_gui/

    de

    ProxyPassReverse /:44441/ http://IP_Serveur_LAN:44440/jobscheduler/operations_gui

    Je dirais simplement :

    ProxyPassReverse /:44441/ http://localhost:44440/jobscheduler/operations_gui

    Ta directive

    <Proxy http://IP_Serveur_LAN:*/*> 
    

    est aussi à corriger du coup.

    • Configurer IPTables pour que les connexions arrivant sur le port 80 soit ensuite perçu comme de source "localhost" et qu'elles soient redirigés vers Apache (j'ai pris le port 44441, un peu au hasard je l'avoue).

    Tu peux faire écouter le proxy apache directement sur le port 80, cette étape de redirection n'est pas nécessaire si tu ne mets pas ProxyPreserveHost à On l’hôte passé à ton application proviendra déjà de localhost puisque tu l'attaques par là ;)

    Mon problème, c'est que ça ne fonctionne pas et que j'arrive pas à identifier d'où proviennent les erreurs de fonctionnement.

    Il va falloir passer par là, aller lire les logs, voir où les connexions aboutissent et si non où la chaîne se rompt, sans cela tu n'avanceras pas.

    • [^] # Re: Simplification et vérification des logs

      Posté par  . Évalué à 4.

      Peut-être déjà commencer par tester le proxy apache sans authentification.
      Quand tu as validé, ajoutes kerberos.

    • [^] # Re: Simplification et vérification des logs

      Posté par  . Évalué à 2. Dernière modification le 01 avril 2015 à 14:00.

      Bonjour :)

      Merci beaucoup Christophe ton message m'a grandement aidé !
      Je me passe donc de IPTables, puisque Apache(httpd) suffit à faire cette redirection en locahost.
      J'ai procédé comme on me l'a conseillé, d'abord sans l'authentification puis ensuite avec (merci tetaclac).

      Au niveau du proxy avec authentification, c'est tout bon !
      Par-contre j'ai un nouveau problème qui m'est apparu, et j'ai beau chercher je ne vois pas pourquoi j'ai un problème de DNS alors que je suis en localhost.

      Voici donc ma configuration httpd actuelle :

      <VirtualHost *:80>
      ServerName 10.4.65.68
      ProxyPass / http://127.0.0.1:44440
      ProxyPassReverse / http://127.0.0.1:44440
      ProxyPreserveHost Off
      
      <Location />
      AuthName "JOBSCHD Access"
      AuthType Kerberos
      Krb5Keytab  /etc/krb5.ktab
      KrbAuthRealms EXEMPLE.PRIV
      KrbMethodNegotiate On
      KrbMethodK5Passwd On
      require valid-user
      </Location>
      </VirtualHost>

      Quand je me connecte avec mon navigateur, j'obtiens 502 Proxy Error :

      # Proxy Error #
      
      The proxy server received an invalid response from an upstream server.
      The proxy server could not handle the request GET /jobscheduler/operations_gui/.
      
      Reason: DNS lookup failure for: 127.0.0.1:44440jobscheduler

      Voici les logs error de httpd:

      [Wed Apr 01 10:37:55 2015] [debug] proxy_util.c(2026): proxy: HTTP: has acquired connection for (*)
      [Wed Apr 01 10:37:55 2015] [debug] proxy_util.c(2082): proxy: connecting http://[localhost:44440jobscheduler]/operations_gui/ to localhost:44440jobscheduler:80
      [Wed Apr 01 10:37:55 2015] [error] [client 10.4.65.110] proxy: DNS lookup failure for: localhost:44440jobscheduler returned by /jobscheduler/operations_gui/
      [Wed Apr 01 10:37:55 2015] [debug] proxy_util.c(2044): proxy: HTTP: has released connection for (*)

      J'ai donc du mal à comprendre d'où peut provenir cette erreur, qui du coup m'empêche d'accéder à mon application.

      Est ce que c'est bon si je poste cette question en commentaire, ou bien dois-je ouvrir un nouveau sujet ?

      Merci d'avance !
      Bonne journée !
      Guillaume.

      • [^] # Re: Simplification et vérification des logs

        Posté par  . Évalué à 1. Dernière modification le 01 avril 2015 à 14:01.

        AJOUT :

        Dans les logs de mon application,
        si je me connecte directement au port 44440 (ce que je vais bloquer ensuite car par d'authentification), j'ai la ligne suivante:

        IP_PCclient_LAN -  -  [01/avr./2015:09:41:42 +0000] "POST /jobscheduler/engine/command/ HTTP/1.1" 200 0 "http://IP_Serveur_LAN:44440/jobscheduler/operations_gui/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0"

        Alors que si depuis le même PC client, je me connecte sur le port 80, j'obtiens la ligne suivante :

        0:0:0:0:0:0:0:1 -  -  [01/avr./2015:09:42:32 +0000] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0"

        On dirait donc que quand je passe par mon proxy Apache, le serveur lui donne une adresse étrange 0:0:0:0:0:0:0:1, et ne lui donne pas de chemin à atteindre.

        Suis-je suis la bonne voie, ou pas du tout ?
        Si quelqu'un a déjà eu cette erreur, j'accepte tous les conseils volontiers !

        Merci d'avance !
        Guillaume

      • [^] # Re: Simplification et vérification des logs

        Posté par  . Évalué à 4.

        connecting http://[localhost:44440jobscheduler ]/operations_gui/ to localhost:44440jobscheduler:80
        [Wed Apr 01 10:37:55 2015] [error] [client 10.4.65.110] proxy: DNS lookup failure for: localhost:44440jobscheduler returned by /jobscheduler/operations_gui/

        il ne manquerait pas un / entre 44440 et jobscheduler ?

        ca vient de ta config proxy, il manque un / à la fin
        je penses que ca devrait etre ca :

        ProxyPass / http://127.0.0.1:44440/
        ProxyPassReverse / http://127.0.0.1:44440/

        • [^] # Re: Simplification et vérification des logs

          Posté par  . Évalué à 2. Dernière modification le 01 avril 2015 à 15:16.

          Yes sans le slash à la fin ca va moins bien marcher :)
          Et pour l'adresse étrange c'est tout simplement localhost en ipv6.

  • # erreur de config

    Posté par  . Évalué à 2.

    tu dis partout d'utiliser EXEMPLE.PRIV comme REALM

    [libdefaults]
    default_realm = EXEMPLE.PRIV
    dns_lookup_realm = false
    dns_lookup_kdc = false

    […]
    [domain_realm]
    .exemple.priv = EXEMPLE.PRIV
    exemple.priv = EXEMPLE.PRIV

    mais tu n'as configuré que ATMB.PRIV

    [realms]
    ATMB.PRIV = {
    kdc = nomServeurAD.exemple.priv:88
    admin_server = nomServeurAD.exemple.priv:749
    default_domain = exemple.priv
    }

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.