[centos] svn server(subversion) 아파치 https 연동하기

예전부터 종종 해오면서 “해야지, 해야지”했던 svn 서버 설정에 대해 블로깅하려 한다.

지금은 git가 대세라서 git도 좀 써보려하지만 일단 친숙한 svn서버 설정부터 해놓으려는게 목적이다.

서버 환경은 Centos 6.5 이고 minimun을 다운받아서 기본만 설치한 상태이다.

1. 아파치 설치

$> sudo yum install httpd

a. 정상설치 확인

$> rpm -qa httpd
httpd-2.2.15-39.el6.centos.x86_64

b. 아파치 iptables 예외 설정

$>sudo vi /etc/sysconfig/iptables

아래 내용 추가

-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

아파치 svn연동 모듈 설치

$> sudo yum install mod_dav_svn mod_ssl

 

2. 아파치 https 설정

https 키생성(self signing)

$> openssl genrsa -des3 -out cert.key 1024
$> openssl req -new -key cert.key -out cert.csr
$> openssl x509 -req -days 3650 -in cert.csr -signkey cert.key -out cert.crt

키를 특정 경로에 저장, 여기서는 /etc/httpd폴더에 cert폴더를 만듬

$> mkdir /etc/httpd/cert

httpd-svn.conf파일을 /etc/httpd/conf.d/ 경로에 생성 한 뒤,

$> vi /etc/httpd/conf.d/httpd-svn.conf

 

아래 내용을 자신에게 맞도록 설정을 변경한다.

ServerName: 본인의 서버 이름

ServerAlias: 서버의 약칭

AuthUserFile: svn의 repository의 유저 패스워드 파일(뒤에 생성)

AuthzSVNAccessFile: svn의 repository 각 프로젝트의 권한 설정 파일(뒤에 생성)

SSLCertificateFile: 생성한 인증서파일

SSLCertificateKeyFile: 생성한 개인키

<VirtualHost *:443>

ServerName weeppp.com
ServerAlias weeppp.com
DocumentRoot "/var/www/svn"

<Location /test>
    DAV                svn
#   SVNPath             "/repository/sample"
    SVNParentPath      "/repository"
    SVNListParentPath  On
    SVNIndexXSLT       "/repos-web/view/repos.xsl"

    AuthType           Basic
    AuthName           "SVN Repository"
    AuthUserFile       "/repository/.passwd"
    AuthzSVNAccessFile "/repository/.authz"
    Require            valid-user
</Location>

# Use separate log files for the SSL virtual host; note that LogLevel
# is not inherited from httpd.conf.
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn

#   SSL Engine Switch:
#   Enable/Disable SSL for this virtual host.
SSLEngine on

#   SSL Protocol support:
# List the enable protocol levels with which clients will be able to
# connect.  Disable SSLv2 access by default:
SSLProtocol all -SSLv2

#   SSL Cipher Suite:
# List the ciphers that the client is permitted to negotiate.
# See the mod_ssl documentation for a complete list.
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW

#   Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate.  If
# the certificate is encrypted, then you will be prompted for a
# pass phrase.  Note that a kill -HUP will prompt again.  A new
# certificate can be generated using the genkey(1) command.
#SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateFile /etc/cert/server.crt

#   Server Private Key:
#   If the key is not combined with the certificate, use this
#   directive to point at the key file.  Keep in mind that if
#   you've both a RSA and a DSA private key you can configure
#   both in parallel (to also allow the use of DSA ciphers, etc.)
#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateKeyFile /etc/cert/server.key

#   Server Certificate Chain:
#   Point SSLCertificateChainFile at a file containing the
#   concatenation of PEM encoded CA certificates which form the
#   certificate chain for the server certificate. Alternatively
#   the referenced file can be the same as SSLCertificateFile
#   when the CA certificates are directly appended to the server
#   certificate for convinience.
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt

#   Certificate Authority (CA):
#   Set the CA certificate verification path where to find CA
#   certificates for client authentication or alternatively one
#   huge file containing all of them (file must be PEM encoded)
#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt

#   Client Authentication (Type):
#   Client certificate verification type and depth.  Types are
#   none, optional, require and optional_no_ca.  Depth is a
#   number which specifies how deeply to verify the certificate
#   issuer chain before deciding the certificate is not valid.
#SSLVerifyClient require
#SSLVerifyDepth  10

#   Access Control:
#   With SSLRequire you can do per-directory access control based
#   on arbitrary complex boolean expressions containing server
#   variable checks and other lookup directives.  The syntax is a
#   mixture between C and Perl.  See the mod_ssl documentation
#   for more details.
#<Location />
#SSLRequire (    %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
#            and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
#            and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
#            and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
#            and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20       ) \
#           or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
#</Location>

#   SSL Engine Options:
#   Set various options for the SSL engine.
#   o FakeBasicAuth:
#     Translate the client X.509 into a Basic Authorisation.  This means that
#     the standard Auth/DBMAuth methods can be used for access control.  The
#     user name is the `one line' version of the client's X.509 certificate.
#     Note that no password is obtained from the user. Every entry in the user
#     file needs this password: `xxj31ZMTZzkVA'.
#   o ExportCertData:
#     This exports two additional environment variables: SSL_CLIENT_CERT and
#     SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
#     server (always existing) and the client (only existing when client
#     authentication is used). This can be used to import the certificates
#     into CGI scripts.
#   o StdEnvVars:
#     This exports the standard SSL/TLS related `SSL_*' environment variables.
#     Per default this exportation is switched off for performance reasons,
#     because the extraction step is an expensive operation and is usually
#     useless for serving static content. So one usually enables the
#     exportation for CGI and SSI requests only.
#   o StrictRequire:
#     This denies access when "SSLRequireSSL" or "SSLRequire" applied even
#     under a "Satisfy any" situation, i.e. when it applies access is denied
#     and no other module can change it.
#   o OptRenegotiate:
#     This enables optimized SSL connection renegotiation handling when SSL
#     directives are used in per-directory context.
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
    SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>

#   SSL Protocol Adjustments:
#   The safe and default but still SSL/TLS standard compliant shutdown
#   approach is that mod_ssl sends the close notify alert but doesn't wait for
#   the close notify alert from client. When you need a different shutdown
#   approach you can use one of the following variables:
#   o ssl-unclean-shutdown:
#     This forces an unclean shutdown when the connection is closed, i.e. no
#     SSL close notify alert is send or allowed to received.  This violates
#     the SSL/TLS standard but is needed for some brain-dead browsers. Use
#     this when you receive I/O errors because of the standard approach where
#     mod_ssl sends the close notify alert.
#   o ssl-accurate-shutdown:
#     This forces an accurate shutdown when the connection is closed, i.e. a
#     SSL close notify alert is send and mod_ssl waits for the close notify
#     alert of the client. This is 100% SSL/TLS standard compliant, but in
#     practice often causes hanging connections with brain-dead browsers. Use
#     this only for browsers where you know that their SSL implementation
#     works correctly.
#   Notice: Most problems of broken clients are also related to the HTTP
#   keep-alive facility, so you usually additionally want to disable
#   keep-alive for those clients, too. Use variable "nokeepalive" for this.
#   Similarly, one has to force some clients to use HTTP/1.0 to workaround
#   their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
#   "force-response-1.0" for this.
SetEnvIf User-Agent ".*MSIE.*" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

#   Per-Server Logging:
#   The home of a custom SSL log file. Use this when you want a
#   compact non-error SSL logfile on a virtual host basis.
CustomLog logs/ssl_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

</VirtualHost>

 

 

아파치 설정 폴더로 이동

$> cd /etc/httpd/conf

설정 파일 오픈 및 내용 변경

  • 서버이름은 해당 도메인이나 아이피등으로 변경
  • User와 Group은 아래와 같이 아파치로 변경
ServerName weeppp.com
User apache
Group apache

/etc/httpd/conf 디렉토리에 extra 폴더 생성 및 파일 생성

$> mkdir extra
$> cd extra
$> vi httpd-svn.conf

httpd-svn.conf 파일안에 아래 내용 복사

##############################################################
# SVN
##############################################################

LoadModule dav_svn_module   modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so

<VirtualHost *:443>
    ServerName  weeppp.com
    ServerAlias  weeppp.com
    DocumentRoot "/data/webapps/svn/public_html"
    ServerAdmin  admin@gmail.com

    SetEnvIf Request_URI "\.(gif)|(jpg)|(swf)|(png)$" image_log

    CustomLog    "logs/svn_access_log.log"       common env=!image_log
    CustomLog    "logs/svn_access_image_log.log" common env=image_log
    ErrorLog     "logs/svn_error_log.log"

    <Location /svn>
        DAV                svn
        #SVNPath             "/repository/svn/repo/devsample"
        SVNParentPath /repository
#        SVNParentPath      "/repository/svn/devsample"
#        SVNListParentPath  On
        SVNIndexXSLT       "/repos-web/view/repos.xsl"

        AuthType           Basic
        AuthName           "Weep SVN Repository"
        AuthUserFile       "/repository/.passwd"
        AuthzSVNAccessFile "/repository/.authz"
        Require            valid-user
    </Location>
</VirtualHost>

여기서는 SVNParentPath를 설정해줘서 루트아래의 모든 프로젝트를 접근 가능하도록 함

3. SVN 설정

svn 저장소를 원하는 경로에 생성 및 이동

$> mkdir /repository
$> cd /repository

svn 저장소 소유자 변경

$> chown -R apache.apache /repository

sample프로젝트 생성

$> svnadmin create /repository/sample

프로젝트 소유자 및 권한 변경

$> chown -R apache.apache sample
$> chcon -R -t httpd_sys_content_t sample

svn 계정생성

$> htpasswd -c -m .passwd USER

.authz파일 생성

$> vi /repository/.authz

.authz파일에 하단 내용 추가

admin 그룹에 속한 계정(현재는 weeppp)에게 sample 프로젝트의 read/write 권한을 모두 주는것을 의미한다.

[groups]
admin=weeppp

[sample:/]
@admin = rw

 

.passwd 파일과 .authz파일 소유자를 apache로 변경한다

$> chown apache.apache .passwd
$> chown apache.apache .authz

problems with SELinux context/lables 요 문제가 있으므로 아래 명령을 실행한다.

$> chcon -t httpd_sys_content_t .authz
$> chcon -t httpd_sys_content_t .passwd

위의 명령어들을 잊지 않도록 /repository 폴더안에 ReadMe 파일로 저장해둔다.

#user create
htpasswd -c -m .passwd USER
#user add
htpasswd -m .passwd USER

#create svn repository
svnadmin create /repository/sample
chown -R apache.apache sample
chcon -R -t httpd_sys_content_t sample

subversion 재시작

$> /etc/init.d/svnserve stop
$> /etc/init.d/svnserve start

아파치 재시작

$> /etc/init.d/httpd restart

svn client를 이용해서 서버에 접근해본다.

https://weeppp.com/test/sample

checkout 하고 인증 받은 뒤에 svn을 이용하면 된다.

 

 

 

[linux/unix] svn 사용 간단 tip

리눅스 유닉스에서 작업후 svn add 할 때에 추가할 파일과 그렇지 않고 로컬에서만 쓰는 파일(이를테면 테스트 파일 따위)들이 있는 경우가 있다.

이럴 경우 svn add가 불편한데 이때 사용하는 간단 스크립트 tip

svn status | grep "^?" | awk '{print $2}'

특정 파일이나 폴더를 제외하고 싶을 경우는 뒤에 파이프(|)추가후 egrep 추가
예로 tmp 폴더를 제외하고 싶을 경우.

svn status | grep "^?" | awk '{print $2}' |egrep -ve '^tmp$'

위의 스크립트를 적당히 수정한 후 파일로 저장

예를 들어 commit.sh 파일에 저장했을 경우에 svn add

svn add `./commit.sh`

바이너리 파일들(.so, .a 파일 등)도 추가하고 싶을 경우

svn add `./commit.sh` --no-ignore

간단 팁 완료.