Substituição do Apache 2.4 para mod_auth_shadow?

3

Meu empregador está executando o RHEL 6.xe o Apache httpd 2.2 há muitos anos. No momento, estamos no processo de migração para o novo hardware que executa o RHEL 7.1 e o Apache httpd 2.4. Nosso site atual tem vários locais que contêm material para download para diferentes conjuntos de clientes. Todos os clientes têm contas do sistema na caixa do servidor. Atualmente, controlamos o acesso aos locais com base na participação no grupo de usuários do cliente.

Por exemplo:

<Location /xyzzy/*>
    AuthName "xyzzy product support"
    AuthShadow on
    AuthType Basic
    require group xyzzy
    Options Includes ExecCGI Indexes FollowSymLinks MultiViews
</Location>

Estamos usando com sucesso o mod_auth_shadow para implementar esse controle de acesso no Apache 2.2. No entanto, descobrimos que este módulo não carregará sob 2.4 porque o módulo chama ap_requires() , que não está presente em 2.4.

Percebemos que o RHEL 7 por padrão é executado

/usr/sbin/saslauthd -m /run/saslauthd -a pam

então eu estive olhando para usar o PAM através de mod_authn_sasl como um substituto para mod_auth_shadow. Eu tive sucesso parcial com essa configuração do Apache:

<Location /xyzzy/*>
    AuthType Basic
    AuthName "xyzzy product support"
    AuthBasicProvider sasl
    AuthBasicAuthoritative On
    AuthSaslPwcheckMethod saslauthd
    Require valid-user
</Location>

combinado com esse arquivo /etc/pam.d/http :

#%PAM-1.0
auth       include      password-auth
auth       include      pam_group
account    include      password-auth

Com esta combinação qualquer usuário com credenciais de login válidas pode acessar o local xyzzy. Eu acredito que isso valida que a conexão básica entre Apache - > saslauthd - > O PAM está funcionando. Mas esse não é o nível de granularidade que estamos procurando.

Esta configuração alternativa do httpd:

<Location /xyzzy/*>
    AuthType Basic
    AuthName "xyzzy product support"
    AuthBasicProvider sasl
    AuthBasicAuthoritative On
    AuthSaslPwcheckMethod saslauthd
    Require group xyzzy
</Location>

gera este erro no log do httpd:

AH01664: No group file was specified in the configuration

Isso sugere que o httpd não está passando pelo saslauthd para validar a associação ao grupo. Até agora, eu não encontrei uma diretiva httpd que forçaria a autenticação de grupo através de sasl da maneira que a autenticação de usuário / senha faz.

(Por que estou usando os arquivos passwd, shadow e group do sistema para autenticação em vez de um banco de dados separado para http? Alguns clientes preferem baixar seus arquivos de suporte via ftp em vez de http. Então usamos o sistema para dar clientes relativamente fácil alternar entre os dois protocolos)

Como último recurso, estou preparado para tentar atualizar o mod_auth_shadow para o 2.4. Mas eu nunca codifiquei ou depurei um módulo do apache, então há uma curva de aprendizado desconhecida envolvida nessa abordagem. Então estou completamente aberto a sugestões!

    
por Eric Chevalier 12.09.2016 / 19:59

2 respostas

1

Parece que você já explorou uma opção, aqui estão mais algumas possibilidades, embora pareça que ambas exigirão algum trabalho.

mod_auth_external: link
mod_auth_kerb: link

    
por 12.09.2016 / 22:11
0

Depois de olhar algumas alternativas, incluindo aquelas sugeridas pelo Unbel, eu decidi ir em frente e tentar reescrever o mod_auth_shadow original para ser compatível com a arquitetura de autenticação / autorização atual. Eu criei um módulo muito básico e despojado modelado um pouco depois do módulo mod_authnz_ldap.

/*
 * mod_auth_shadow.c
 *
 * An apache module to authenticate using the /etc/shadow file.
 * This module interacts with another program "validate", which
 * is setuid root.  Thus the /etc/shadow file can remain 
 * root:root 0400.
 *
 * Author: Brian Duggan <[email protected]>
 * Some code was taken from the sample code supplied with
 * _Apache Modules_ by Stein and MacEachern.  Parts of this
 * were also influenced by mod_auth.c.
 *
 * Adapted for Apache2: Bernard du Breuil 
 *  <[email protected]>
 * I went back to mod_auth.c to see how it was converted.
 *
 * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 */

#include "apr_strings.h"
#include "ap_config.h"

#include "httpd.h"  
#include "http_config.h"  
#include "http_core.h"  
#include "http_log.h"  
#include "http_protocol.h"  
#include "http_request.h"  

#include "mod_auth.h"

#include <shadow.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <pwd.h>
#include <grp.h>
#include "validate.h"


static const char module_name[] = "authnz_shadow_module";


static authn_status authn_shadow_check_password(request_rec *r, const char *user,
                                              const char *password)
{
    return AUTH_GRANTED;
}


static authz_status valid_user_check_authorization(request_rec *r,
                                              const char *require_args,
                                              const void *parsed_require_args)
{
    return AUTH_GRANTED;
}


static authz_status group_check_authorization(request_rec *r,
                                              const char *require_args,
                                              const void *parsed_require_args)
{
    return AUTH_GRANTED;
}




typedef struct
{
    int auth_shadow_flag; /* 1 for yes, 0 for no */
}
auth_shadow_config_rec;


static const authn_provider authn_shadow_provider =
{
    &authn_shadow_check_password,
    NULL,
};


static const authz_provider authz_valid_user_provider =
{
    &valid_user_check_authorization,
    NULL,
};


static const authz_provider authz_group_provider =
{
    &group_check_authorization,
    NULL,
};


static void register_hooks(apr_pool_t *p)
{
    /* Register authn provider */
    ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "shadow",
                              AUTHN_PROVIDER_VERSION,
                              &authn_shadow_provider, AP_AUTH_INTERNAL_PER_CONF);

    /* Register authz providers */
    ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "shadow-valid-user",
                              AUTHZ_PROVIDER_VERSION,
                              &authz_valid_user_provider,
                              AP_AUTH_INTERNAL_PER_CONF);
    ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "shadow-group",
                              AUTHZ_PROVIDER_VERSION,
                              &authz_group_provider,
                              AP_AUTH_INTERNAL_PER_CONF);
}


static void *create_auth_shadow_dir_config(apr_pool_t *p, char *d)
{
    auth_shadow_config_rec *sec =
    (auth_shadow_config_rec *) apr_palloc(p, sizeof(*sec));
    sec->auth_shadow_flag = 0;  
    return sec;
}


static const command_rec auth_shadow_cmds[] =
{
    AP_INIT_FLAG("AuthShadow", ap_set_flag_slot,
    (void *)APR_OFFSETOF(auth_shadow_config_rec, auth_shadow_flag),
        OR_AUTHCFG, "On or Off depending on whether to use /etc/shadow"),
    {NULL}
};


module AP_MODULE_DECLARE_DATA authnz_shadow_module = 
{
    STANDARD20_MODULE_STUFF, 
    create_auth_shadow_dir_config , /* dir config creator */
    NULL,                  /* merge  per-dir    config structures */
    NULL,                  /* create per-server config structures */
    NULL,                  /* merge  per-server config structures */
    auth_shadow_cmds,      /* [config file] command table */
    register_hooks     /* register hooks */
};

Neste momento, estou apenas tentando entender a sequência lógica geral dos módulos de autenticação. Eu criei um diretório de teste seguro no meu servidor web definido como:

<Location /secure>
    AuthName SecureDocument
    AuthType Basic
    AuthBasicProvider shadow
    AuthShadow on
    Require shadow-valid-user
    Require shadow-group xyzzy
</Location>

E aqui é onde eu fico muito confuso: durante os testes, descubro que as rotinas valid_user_check_authorization e group_check_authorization são chamadas com r->user definido como NULL. Mas a rotina de autenticação authn_shadow_check_password é never invocada.

Como codificado, o módulo mod_authnz_ldap.c parece implicar que a autorização de autenticação e pode ser combinada em um único módulo. Mas estou assumindo que a função de autenticação, se presente, será sempre chamada antes de qualquer função de autorização. Além disso, suponho que, se as credenciais fornecidas pelo navegador forem válidas de acordo com a função de autenticação, o ID do usuário será passado para as funções de autorização subseqüentes. Mas não encontrei nenhuma documentação definitiva sobre esse assunto de uma forma ou de outra.

Estou aberto a sugestões, sugestões e correções de minhas suposições!

    
por 28.09.2016 / 21:26