Bitnami Redmine과 SVN + Git을 자동으로 연결하기

일차 작업을 했는데, 사용자 관리가 영 찜찜해 Remine 사용자 정보를 이용해 SVN과 Git 접근을 제한하는 방식을 적용해 본다.

우선 https://docs.bitnami.com/installer/apps/redmine/에서 SVN과 Git의 고급 연동 부분을 참고했는데, 이게 실제 우리쪽 환경과는 맞지 않는다. 특히 DNS에 등록치 않고 IP로 접근해야 하는 시스템인지라 뭔가 헷갈린다. 게다라 Git의 경우에는 git-http-backend가 아닌 추가 툴을 추가해 사용하기 때문에 뭔가 꼬일 것 같다.

그래서, 우선은 일차 작업한 환경에서 조금씩 변경에 들어간다.

여기를 참고해 다음 사항들을 적용한다.

/opt/redmine-~~~/apache2/conf/httpd.conf에 사용할 모듈 등록 (DAV, SVN, Perl)
/opt/redmine-~~~/apache2/bin/envvars에 Perl 작업환경 등록 (LD_LIBRARY_PATH)

Redmine.pm 파일을 Perl 모듈 폴더(/opt/redmine-~~~/perl/lib/site_perl/5.16.3/*/Apache2/)에 복사. (Bitnami 패키지 버전에 따라 수정 필요)

여기까지 마쳤으면, httpd의 각 디렉토리 접근 권한 할당 방법을 변경해야 한다.

기존에는 bitnami.conf에서 git 관련된 부분을, httpd-app.conf에서 svn 관련된 부분을 설정했는데, 원래 패키지 의도에 맞도록 bitnami.conf는 원상 복귀시키고, httpd-app.conf(/opt/redmine-~~~/apps/redmine/conf/에 위치)파일에 모든 설정을 몰아 넣는다.

결과적으로 /opt/redmine-~~~/apache2/conf/bitnami/bitnami.conf의 내용은 다음과 같다.
# Default Virtual Host configuration.
<IfVersion < 2.3 >
  NameVirtualHost *:80
  NameVirtualHost *:443
</IfVersion>
<VirtualHost _default_:80>
  DocumentRoot "/opt/redmine-3.3.2-0/apache2/htdocs"
  <Directory "/opt/redmine-3.3.2-0/apache2/htdocs">
    Options Indexes FollowSymLinks
    AllowOverride All
    <IfVersion < 2.3 >
      Order allow,deny                        
      Allow from all
    </IfVersion>
    <IfVersion >= 2.3 >
      Require all granted
    </IfVersion>
  </Directory>
  # Error Documents
  ErrorDocument 503 /503.html
  # Bitnami applications installed with a prefix URL (default)
  Include "/opt/redmine-3.3.2-0/apache2/conf/bitnami/bitnami-apps-prefix.conf"
</VirtualHost>
# Default SSL Virtual Host configuration.
<IfModule !ssl_module>
  LoadModule ssl_module modules/mod_ssl.so
</IfModule>
Listen 443
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !EDH !RC4"
SSLPassPhraseDialog  builtin
SSLSessionCache "shmcb:/opt/redmine-3.3.2-0/apache2/logs/ssl_scache(512000)"
SSLSessionCacheTimeout  300
<VirtualHost _default_:443>
  DocumentRoot "/opt/redmine-3.3.2-0/apache2/htdocs"
  SSLEngine on
SSLCertificateFile "/opt/redmine-3.3.2-0/apache2/conf/server.crt"
SSLCertificateKeyFile "/opt/redmine-3.3.2-0/apache2/conf/server.key"
          
  <Directory "/opt/redmine-3.3.2-0/apache2/htdocs">
    Options Indexes FollowSymLinks
    AllowOverride All
    <IfVersion < 2.3 >
      Order allow,deny                         
      Allow from all
    </IfVersion>
    <IfVersion >= 2.3 >
      Require all granted
    </IfVersion>
  </Directory>
  # Error Documents
  ErrorDocument 503 /503.html
      
  # Bitnami applications installed with a prefix URL (default)
  Include "/opt/redmine-3.3.2-0/apache2/conf/bitnami/bitnami-apps-prefix.conf"
</VirtualHost>
# Bitnami applications that uses virtual host configuration
Include "/opt/redmine-3.3.2-0/apache2/conf/bitnami/bitnami-apps-vhosts.conf"
/opt/redmine-~~~/apps/redmine/conf/httpd-app.conf의 내용은 다음과 같다. 저장소 디렉토리, Redmine 설치 위치, Redmine DB의 이름 및 접속 정보는 각자 환경에 맞춰 수정해 주어야 한다.
RewriteEngine On
RewriteRule /<none> / [L,R]
<Directory "/opt/redmine-3.3.2-0/apps/redmine/htdocs/public">
    Options -MultiViews
    AllowOverride All
    <IfVersion < 2.3 >
        Order allow,deny
        Allow from all
    </IfVersion>
    <IfVersion >= 2.3>
        Require all granted
    </IfVersion>
  
    PassengerEnabled on
    SetEnv RAILS_RELATIVE_URL_ROOT "/redmine"
    PassengerAppRoot "/opt/redmine-3.3.2-0/apps/redmine/htdocs/"
    <IfModule pagespeed_module>
        ModPagespeedDisallow "*"
    </IfModule>
    Include "/opt/redmine-3.3.2-0/apps/redmine/conf/banner.conf"
</Directory>
PerlLoadModule Apache2::Redmine
<Location /svn>
  DAV svn
  SVNParentPath /opt/svn
  Order deny,allow
  Deny from all
  Satisfy any
  PerlAccessHandler Apache::Authn::Redmine::access_handler
  PerlAuthenHandler Apache::Authn::Redmine::authen_handler
  AuthType Basic
  AuthName "Subversion Repository"
#  AuthUserFile "/opt/svn/users"
  AuthUserFile "/dev/null"
  Require valid-user
  ## for mysql
  RedmineDSN "DBI:mysql:database=bitnami_redmine;host=localhost;mysql_socket=/opt/redmine-3.3.2-0/mysql/tmp/mysql.sock"
  RedmineDbUser "bitnami"
  RedmineDbPass "암호"
  #You can find this value at installdir/apps/redmine/htdocs/config/database.yml
</Location>
SetEnv GIT_PROJECT_ROOT /opt/gitrepos
SetEnv GIT_HTTP_EXPORT_ALL
SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER
ScriptAlias /git/ /opt/redmine-3.3.2-0/git/libexec/git-core/git-http-backend/
RewriteCond %{QUERY_STRING} service=git-receive-pack [OR]
RewriteCond %{REQUEST_URI} /git-receive-pack$
RewriteRule ^/git/ - [E=AUTHREQUIRED:yes]
<Directory /opt/redmine-3.3.2-0/git>
  Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
  AllowOverride None
  <IfVersion < 2.3 >
    Order allow,deny
    Allow from all
  </IfVersion>
  <IfVersion >= 2.3 >
    Require all granted
  </IfVersion>
</Directory>
Alias /git /opt/gitrepos
PerlLoadModule Apache2::Redmine
<Location /git>
  Options Indexes FollowSymLinks MultiViews
  AuthType Basic
  AuthName "Git Repository"
#  AuthUserFile "/opt/svn/users"
  AuthUserFile "/dev/null"
  Require valid-user
  PerlAccessHandler Apache::Authn::Redmine::access_handler
  PerlAuthenHandler Apache::Authn::Redmine::authen_handler
  ## for mysql
  RedmineDSN "DBI:mysql:database=bitnami_redmine;host=localhost;mysql_socket=/opt/redmine-3.3.2-0/mysql/tmp/mysql.sock"
  RedmineDbUser "bitnami"
  RedmineDbPass "암호"
  #You can find this value at installdir/apps/redmine/htdocs/config/database.yml
  RedmineGitSmartHttp yes
</Location>
PassengerPreStart http://127.0.0.1:80/redmine

복잡해 보이지만, Redmine과 연동하기 위한 Perl 모듈을 지정해 주고, 각 디렉토리 또는 Location의 권한 지정을 위해 Perl 모듈을 이용해 DB를 뒤져 결과를 유추하도록 한다. 접근하고자 하는 위치에 해당하는 프로젝트 소속 사용자인지 확인하고, 해당 사용자의 암호를 비교해 유효한 사용자인지 검사한다. SVN 저장소에 대해서는 Perl 모듈 연동만, Git 저장소에 대해서는 git-http-backend와 Perl 연동 모두 지정한다.

이제 웹 서비스를 재시작 시킨다.
sudo /opt/redmine-~~~/ctlscript.sh restart apache
이제, 남은 것은 저장소 관리 방법을 정리해 주는 것.

우선 앞에서 사용한 Redmine.pm 파일의 앞부분 설명을 잘 읽어보면 저장소의 작명 기준에 대한 설명이 있다. 즉, 프로젝트의 identifier와 맞춰야 한다는 것. 이게 안 되면 DB를 뒤질 때 디렉토리와 사용자의 권한 관계를 찾을 수 없어 httpd 에러 로그에 [auth_basic] error user XXXX not found라는 에러가 뜬다.

만약 기존에 만들어 둔 저장소가 있었다면 sudo mv __old_name__ __new_name__으로 변경하고, 권한을 변경(sudo chown -R daemon:daemon __proj_dir_name__)하고, Redmine에서 새로 지정해 주면 된다. 만약 새로 만드는 경우라면 다음 스크립트 내용을 참고해 SVN과 Git 저장소를 각각 생성할 수 있다.

SVN 저장소 생성용(create_svn_proj.sh)
#!/bin/bash
svnadmin=/opt/redmine-3.3.2-0/subversion/bin/svnadmin
REPO=$1
if [ "$REPO" = "" ]; then
  echo "Usage: ./create_project.sh [PROJECT_NAME]"
  exit 1
fi
$svnadmin create --fs-type fsfs $REPO

chown -R daemon:daemon $REPO

Git 저장소 생성용(create_git_proj.sh)
#!/bin/bash
git=/opt/redmine-3.3.2-0/git/bin/git
WORKDIR=`pwd`
REPO=$1
if [ "$REPO" = "" ]; then
  echo "Usage: ./create_project.sh [PROJECT_NAME]"
  exit 1
fi

# create dir
echo $REPO
mkdir -p $REPO
cd $REPO

# init repo
$git init --bare
#touch git-daemon-export-ok
cp hooks/post-update.sample hooks/post-update
#$git config http.receivepack true # true will enable anonymous push
$git update-server-info
chown -R daemon:daemon .

# done
cd $WORKDIR

이제 서버 내/외부에서 http://__server_name_ip__/[git or svn]/__project_name__으로 접속하면 되고, 이 때 묻는 사용자 아이디와 암호는 Remine 계정 아이디와 암호를 쓰면 된다.

덧1.
한 발 더 나아가 Remine 페이지를 이용해 자동으로 저장소를 생성하는 방법도 동작하는지 확인해 볼 수 있다. Subersion의 경우 API 키 값 등록과 같은 것을 수행하지 않았기 때문에 아마도 제대로 동작하지 않을 듯 싶다. Git의 경우 Perl 스크립트에서 처리하지 않을까?
해 봐야 알 듯.

덧2.
httpd-app.conf 파일이 여전히 지저분하다. 불필요한 부분을 들어 내면 더 깔끔해 질 것.

댓글

이 블로그의 인기 게시물

환경개선부담금

[DevTip] Windows에서 tail 쓰기...