quinta-feira, 8 de março de 2012

Alfresco - Configuração do CIFS + Kerberos




Após muito tentar e estudar consegui fazer o Alfresco funcionar perfeitamente com o CIFS. Bom primeiramente tentei configura-lo junto ao Samba (estava sem opções), mas de nenhum jeito o treco queria funcionar.


Alfresco roda independente do Samba, mas pelo menos uma coisa boa deu certo ao perdemos um tempo configurando o Samba. Viu-se que a sua autenticação usando Kerberos atendia perfeitamente as requisições. Então passamos a configurar o Alfresco para que também utiliza-se a autenticação do Kerberos no CIFS, em vez do Passthru.
:D

As configurações do sistema são as seguintes:

- Sistema Operacional: Debian Squeeze (6.0.4)

- Alfresco: 4.1.a (compilação da HEAD)

As configurações da rede:

- Deve ser acessado por Windows XP, 32 bits

- Deve ser acessado por Windows 7, 64 bits


Para a configuração básica do Alfresco + Kerberos foi usado o manual disponível no site do Alfresco, visto nesse link: http://docs.alfresco.com/4.0/index.jsp? ... props.html


Essas configurações bastaram para realizar a troca de autenticação de usuários via HTTP, mas não possibilitava a integração com o CIFS. Isso gerou um certo desanimo, pois todas as tentativas pareciam nulas e os resultados não saiam. Após uma longa busca achei um forum que tratava de um erro semelhante com autenticação do CIFS usando Kerberos, nele era sugerido que a classe para autenticação deveria ser uma intância de org.alfresco.repo.security.authentication.SimpleAcceptOrRejectAllAuthenticationComponentImp.


Segue os arquivos de configuração.


/opt/alfresco/tomcat/webapps/alfresco/WEB-INF/classes/alfresco/authentication-services-context.xml

 ...

<!-- The chaining authentication component -->
   <!--bean id="authenticationComponent"
      class="org.alfresco.repo.security.authentication.subsystems.SubsystemChainingAuthenticationComponent"
      parent="authenticationComponentBase"-->
   <bean id="authenticationComponent"
      class="org.alfresco.repo.security.authentication.SimpleAcceptOrRejectAllAuthenticationComponentImp"
      parent="authenticationComponentBase">
      <property name="nodeService">
         <ref bean="nodeService" />
      </property>
      <property name="personService">
         <ref bean="personService" />
      </property>
      <property name="transactionService">
         <ref bean="transactionService" />
      </property>
      <property name="applicationContextManager">
         <ref bean="Authentication" />
      </property>
      <property name="sourceBeanName">
         <value>authenticationComponent</value>
      </property>
   </bean>

...



/opt/alfresco/tomcat/shared/classes/alfresco/extension/file-serveres-custom.xml

<alfresco-config area="file-servers">

   <config evaluator="string-compare" condition="Filesystem Security" replace="true"> 
      <!-- Enterprise authentication with Kerberos -->
      <authenticator type="enterprise"/>
         <KDC>${kerberos.authentication.server.kdc}</KDC>
         <Realm>${kerberos.authentication.realm}</Realm>
         <Password>${kerberos.authentication.cifs.password}</Password>
         <!--LoginEntry>${kerberos.authentication.cifs.configEntryName}</LoginEntry-->
         <Principal>${kerberos.authentication.cifs.principal}<Principal>
         <Debug/>
         <kerberosDebug/>
      </authenticator>
   </config>

   <config evaluator="string-compare" condition="CIFS Server" replace="true">
      <serverEnable enabled="${cifs.enabled}"/>
     
      <host name="${cifs.serverName}" domain="${cifs.domain}"/>
      <comment>Intranet Server</comment>

      <!-- Set to the broadcast mask for the subnet -->
      <broadcast>${cifs.broadcast}</broadcast>
     
      <!-- Set to the IP for the adapter for Java socket -->
      <bindto>${cifs.bindto}</bindto>

      <!-- Use Java socket based NetBIOS over TCP/IP and native SMB on linux -->
       <!-- Can be mapped to non-privileged ports, then use firewall rules to forward
            requests from the standard ports -->
      <tcpipSMB port="${cifs.tcpipSMB.port}" ipv6="${cifs.ipv6}" platforms="linux,solaris,macosx"/>
      <netBIOSSMB sessionPort="${cifs.netBIOSSMB.sessionPort}" namePort="${cifs.netBIOSSMB.namePort}" datagramPort="${cifs.netBIOSSMB.datagramPort}" platforms="linux,solaris,macosx"/>

      <!-- Announce the server to the EMPINT/domain -->
      <!-- Use enabled="false" attribute to disable announcements -->             
      <hostAnnounce interval="5" enabled="${cifs.hostannounce}"/>

      <!-- Use Win32 NetBIOS interface on Windows -->
      <!--Win32NetBIOS/-->

      <!-- Announce the server to the EMPINT/domain -->
      <!-- Use enabled="false" attribute to disable announcements -->             
      <!--Win32Announce interval="5" enabled="${cifs.hostannounce}"/-->
     
      <!-- CIFS Passthru authentication -->
      <!-- Also see the <DomainMappings> config in the 'Filesystem Security' section below -->
      <!--
      <authenticator type="passthru">
        <Server>${passthru.authentication.servers}</Server>
   <Domain>${passthru.authentication.domain}</Domain>
        <protocolOrder>${passthru.authentication.protocolOrder}</protocolOrder>
        <offlineCheckInterval>${passthru.authentication.offlineCheckInterval}</offlineCheckInterval>
      </authenticator>
      -->

      <!-- CIFS Enterprise authentication with Kerberos -->
      <authenticator type="enterprise"/>
         <KDC>${kerberos.authentication.server.kdc}</KDC>
         <Realm>${kerberos.authentication.realm}</Realm>
         <Password>${kerberos.authentication.cifs.password}</Password>
         <!--LoginEntry>${kerberos.authentication.cifs.configEntryName}</LoginEntry-->
         <Principal>${kerberos.authentication.cifs.principal}<Principal>
         <Debug/>
         <kerberosDebug/>
      </authenticator>
     
      <!-- Disable the use of asynchronous sockets/NIO code -->
      <!--
      <disableNIO/>
      -->
     
      <!-- Disable the use of JNI code -->
      <!-- Only currently affects Windows -->
      <!--
      <disableNativeCode/>
      -->
     
      <!-- Session timeout, in seconds -->
      <!-- Defaults to 15 minutes, to match the default Windows client setting        -->
      <!-- If no I/O is received within that time the session is closed by the server -->
      <!--
      <sessionTimeout>${cifs.sessionTimeout}</sessionTimeout>
      -->
     
      <!-- Enable WINS if used for NetBIOS name lookups -->
      <!--
      <WINS>
         <primary>${cifs.WINS.primary}</primary>
         <secondary>${cifs.WINS.secondary}</secondary>
      </WINS>
      -->
     
      <!-- CIFS server debug settings -->
      <!-- Enable 'log4j.logger.org.alfresco.fileserver=debug' in log4j.properties file -->
      <sessionDebug flags="NetBIOS,Pkttype,Streams,Negotiate,Socket,Tree,Errors,State"/>
   </config>

   <config evaluator="string-compare" condition="FTP Server" replace="true">
      <serverEnable enabled="${ftp.enabled}"/>
     
      <!-- Run on a non-privileged port -->
      <port>${ftp.port}</port>

      <!-- IPv6 support -->
      <IPv6 state="${ftp.ipv6}"/>

      <rootDirectory>/${filesystem.name}/</rootDirectory>

      <!-- FTP authentication -->
      <!-- Available types are 'alfresco' and 'passthru' -->
      <authenticator type="alfresco" />
           
      <!-- FTP server debug settings -->
      <!-- Enable 'log4j.logger.org.alfresco.fileserver=debug' in log4j.properties file -->
      <debug flags="File,Search,Error,Directory,Info,DataPort"/>

   </config>
   
   <config evaluator="string-compare" condition="NFS Server" replace="true">
      <serverEnable enabled="${nfs.enabled}"/>

      <!-- Map NFS user/group ids to Alfresco users -->     
      <rpcAuthenticator>
         <userMappings>
            <user name="admin" uid="0" gid="0"/>
         </userMappings>
      </rpcAuthenticator>
   </config>
   
   <config evaluator="string-compare" condition="Filesystems" replace="true">
      <filesystems>

         <filesystem name="${filesystem.name}">
            <store>workspace://SpacesStore</store>
            <rootPath>/app:company_home</rootPath>

            <!-- Add a URL file to each folder that links back to the web client -->
            <urlFile>
               <filename>__Alfresco.url</filename>
               <webpath>http://${localname}:8080/alfresco/</webpath>
            </urlFile>

            <!-- Mark locked files as offline -->
            <offlineFiles/>

            <!-- Desktop actions -->

            <desktopActions>
               <global>
                  <path>alfresco/desktop/Alfresco.exe</path>
                  <webpath>http://${localname}:8080/alfresco/</webpath>
               </global>
               <action>
                  <class>org.alfresco.filesys.repo.desk.CheckInOutDesktopAction</class>
                  <name>CheckInOut</name>
                  <filename>__CheckInOut.exe</filename>
               </action>
               <action>
                  <class>org.alfresco.filesys.repo.desk.JavaScriptDesktopAction</class>
                  <name>JavaScriptURL</name>
                  <filename>__ShowDetails.exe</filename>
                  <script>alfresco/desktop/showDetails.js</script>
                  <attributes>anyFiles</attributes>
                  <preprocess>copyToTarget</preprocess>
               </action>

            </desktopActions>

<!--
            <accessControl default="Write">
               <user name="admin" access="Write"/>
               <address subnet="90.1.0.0" mask="255.255.0.0" access="Write"/>
            </accessControl>
-->
         </filesystem>
       
       <!-- AVM virtualization view of all stores/versions for WCM -->
         <avmfilesystem name="AVM">
            <virtualView/>
         </avmfilesystem>
       
      </filesystems>
   </config>
</alfresco-config>



/opt/alfresco/tomcat/shared/classes/salfresco-global.properties

#
# File System
#
filesystem.name=Intranet
#filesystem.acl.global.defaultAccessLevel=
filesystem.domainMappings=EMPINT
filesystem.domainMappings.value.EMPINT.subnet=172.16.0.0
filesystem.domainMappings.value.EMPINT.mask=255.255.0.0

### Authentication ###
authentication.chain=alfrescoNtlm1:alfrescoNtlm,kerberos1:kerberos,passthru1:passthru,ldap1:ldap-ad
alfresco.authentication.allowGuestLogin=true
alfresco.authentication.authenticateCIFS=false
### NTLM ###
#ntlm.authentication.sso.enabled=true
#ntlm.authentication.mapUnknownUserToGuest=true
### Kerberos ###
kerberos.authentication.server.kdc=172.16.1.250
kerberos.authentication.realm=EMPINT.LOCAL
kerberos.authentication.sso.enabled=true
kerberos.authentication.authenticateCIFS=true
kerberos.authentication.cifs.principal=cifs/intranet.empint.local
kerberos.authentication.cifs.configEntryName=AlfrescoCIFS
kerberos.authentication.http.configEntryName=AlfrescoCIFS
kerberos.authentication.cifs.password=uuh@123
kerberos.authentication.http.password=uuh@123
kerberos.authentication.defaultAdministratorUserNames=administrator,intranet
kerberos.authentication.cifs.enableTicketCracking=true
#
# CIFS
#
cifs.enabled=true
cifs.localname=intranet
cifs.serverName=${cifs.localname}
cifs.domain=EMPINT
cifs.broadcast=172.16.255.255
#cifs.bindto=172.16.1.116
cifs.bindto=0.0.0.0
cifs.ipv6=disabled
cifs.hostannounce=true
# Enable the use of asynchronous sockets/NIO code
cifs.disableNIO=false
# Disable the use of JNI code. Only currently affects Windows
cifs.disableNativeCode=true
# Session timeout, in seconds. Defaults to 15 minutes, to match the default Windows client setting.
# If no I/O is received within that time the session is closed by the server
cifs.sessionTimeout=900
# Can be mapped to non-privileged ports, then use firewall rules to forward requests from the standard ports
cifs.tcpipSMB.port=445
cifs.netBIOSSMB.sessionPort=139
cifs.netBIOSSMB.namePort=137
cifs.netBIOSSMB.datagramPort=138
# Optional WINS server primary and secondary IP addresses. Ignored if autoDetectEnabled=true
cifs.WINS.autoDetectEnabled=false
cifs.WINS.primary=1.2.3.4
cifs.WINS.secondary=5.6.7.8
#
# FTP
#
ftp.enabled=true
ftp.port=2121
ftp.ipv6=disabled
#
# NFS
#
nfs.enabled=false
#
# Passthru
#
passthru.authentication.useLocalServer=false
passthru.authentication.domain=EMPINT
passthru.authentication.servers=EMPINT\\srv-domain,172.16.1.250
passthru.authentication.guestAccess=false
passthru.authentication.defaultAdministratorUserNames=administrator,intranet
#Timeout value when opening a session to an authentication server, in milliseconds
passthru.authentication.connectTimeout=5000
#Offline server check interval in seconds
passthru.authentication.offlineCheckInterval=300
passthru.authentication.protocolOrder=TCPIP,NetBIOS
passthru.authentication.sso.enabled=true
passthru.authentication.authenticateCIFS=false
passthru.authentication.authenticateFTP=true
#
# LDAP
#
ldap.authentication.active=false
ldap.authentication.allowGuestLogin=true
ldap.authentication.userNameFormat=%s
ldap.authentication.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
ldap.authentication.java.naming.provider.url=ldap://srv-domain:389
ldap.authentication.java.naming.security.authentication=DIGEST-MD5
ldap.authentication.escapeCommasInBind=false
ldap.authentication.escapeCommasInUid=false
ldap.authentication.defaultAdministratorUserNames=Administrator
ldap.synchronization.active=true
ldap.synchronization.java.naming.security.authentication=DIGEST-MD5
ldap.synchronization.java.naming.security.principal=user.it
ldap.synchronization.java.naming.security.credentials=xpasswd
ldap.synchronization.queryBatchSize=1000
ldap.synchronization.attributeBatchSize=1000
ldap.synchronization.groupQuery=(objectClass\=*)
ldap.synchronization.groupDifferentialQuery=(objectClass\=*)
ldap.synchronization.personQuery=(&(objectClass=top)(&(!(OU=Desligados))(!(CN=ldap sync))))
ldap.synchronization.personDifferentialQuery=(objectClass\=*)
ldap.synchronization.groupSearchBase=OU=Grupos,DC=EMPINT,DC=local
ldap.synchronization.userSearchBase=OU=Usuarios,DC=EMPINT,DC=local
ldap.synchronization.modifyTimestampAttributeName=modifyTimestamp
ldap.synchronization.timestampFormat=yyyyMMddHHmmss'.0Z'
ldap.synchronization.userIdAttributeName=sAMAccountName
ldap.synchronization.userLastNameAttributeName=sn
ldap.synchronization.userEmailAttributeName=mail
ldap.synchronization.userOrganizationalIdAttributeName=company
ldap.synchronization.defaultHomeFolderProvider=userHomesHomeFolderProvider
ldap.synchronization.groupIdAttributeName=cn
ldap.synchronization.groupDisplayNameAttributeName=displayName
ldap.synchronization.groupType=group
ldap.synchronization.personType=user
ldap.synchronization.groupMemberAttributeName=member
ldap.synchronization.enableProgressEstimation=true
synchronization.synchronizeChangesOnly=true
synchronization.import.cron=0 0 0 * * ?
synchronization.syncWhenMissingPeopleLogIn=true
synchronization.syncOnStartup=true
synchronization.autoCreatePeopleOnLogin=true
synchronization.loggingInterval=100
synchronization.workerThreads=2

/opt/alfresco/java/jre/lib/security/java.login.config


Alfresco {
   com.sun.security.auth.module.Krb5LoginModule sufficient;
};
AlfrescoCIFS {
   com.sun.security.auth.module.Krb5LoginModule required
   storeKey=true
   useKeyTab=true
   keyTab="/etc/intranetcifs.keytab"
   principal="cifs/intranet.empint.local@EMPINT.LOCAL";
};
com.sun.net.ssl.client {
   com.sun.security.auth.module.Krb5LoginModule sufficient;
};
other {
   com.sun.security.auth.module.Krb5LoginModule sufficient;
};

/opt/alfresco/java/jre/lib/security/java.security

 ...
#Alfresco login
login.config.url.1=file:${java.home}/lib/security/java.login.config

/etc/krb5.conf

[libdefaults]
   default_realm = EMPINT.LOCAL
# The following krb5.conf variables are only for MIT Kerberos.
   krb4_config = /etc/krb.conf
   krb4_realms = /etc/krb.realms
   kdc_timesync = 1
   ccache_type = 4
   forwardable = true
   proxiable = true
# The following encryption type specification will be used by MIT Kerberos
# if uncommented.  In general, the defaults in the MIT Kerberos code are
# correct and overriding these specifications only serves to disable new
# encryption types as they are added, creating interoperability problems.
#
# Thie only time when you might need to uncomment these lines and change
# the enctypes is if you have local software that will break on ticket
# caches containing ticket encryption types it doesn't know about (such as
# old versions of Sun Java).
        default_tkt_enctypes = rc4-hmac
        default_tgs_enctypes = rc4-hmac
       
# The following libdefaults parameters are only for Heimdal Kerberos.
   v4_instance_resolve = false
   v4_name_convert = {
      host = {
         rcmd = host
         ftp = ftp
      }
      plain = {
         something = something-else
      }
   }
   fcc-mit-ticketflags = true
[realms]
   EMPINT.LOCAL = {
      kdc = srv-domain.empint.local
      admin_server = srv-domain.empint.local
      default_domain = empint.local
      }
[domain_realm]
   .empint.local = EMPINT.LOCAL
   empint.local = EMPINT.LOCAL
[login]
   krb4_convert = true
   krb4_get_tickets = false

Se notarem o Passthru não foi abandonado, pois o FTP ainda funciona com ele. Não testei substitui-lo pelo Kerberos ainda.
Outras configurações de rede que podem ser uteis. Pois precisaram ser feitas para o funcionamento correto da comunicação entre o Windows e o Debian.
/etc/hosts

127.0.0.1       localhost.localdomain   localhost       SRV-ECM.EMPINT.local SRV-ECM
127.0.1.1       SRV-ECM.EMPINT.local localhost       SRV-ECM
172.16.1.116    intranet.empint.local intranet
172.16.1.250    srv-domain.empint.local      srv-domain

Assim o serviço do Alfresco no nosso sistema pode ser acessado pelo endereço de rede: \\intranet.empint.local\Intranet