Apache2 (아파치)의 SSLCertificateChainFile 설정

SSL Chain File 만드는 방법

COMODO PositiveSSL 인증서를 방금 받았는데 이걸 기준으로 설명하면

BS의 인증서는 COMODORSADomainValidationSecureServerCA 인증서가 인증하고
COMODORSADomainValidationSecureServerCA 인증서는 COMODORSAAddTrustCA 인증서가 인증
COMODORSAAddTrustCA 인증서는 AddTrustExternalCARoot 인증서가 인증

BS의 인증서를 위한 체인 파일은 위 인증 과정에 따라

Linux 명령으로 아래처럼

cat COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > some.ca-bundle

Windows에서는 copy 명령으로 + 를 사용해서

copy COMODORSADomainValidationSecureServerCA.crt + COMODORSAAddTrustCA.crt + AddTrustExternalCARoot.crt some.ca-bundle

이걸 아파치 설정에 SSLCertificateChainFile (또는 Apache 1.x에서는 SSLCACertificateFile)으로 설정하고 재시작하면… 끝

AWS EC2에서 실행되는 Ubuntu에 nameserver 설정

기본 nameserver는 .internal 로 끝나는 내부용 DNS가 설정되게 되어있습니다.
이걸 자체 구축한 네임서버로 바꾸려면…

/etc/dhcp/dhclient.conf 파일에서

supersede domain-name “bspfp”;
prepend domain-name-servers 127.0.0.1;

과 같이 명시를 해주시고 리붓… 하시면 해결

아… 잊지마시고… hostname 수정하셔야 귀찮은 경고 문구 뜨는 거 없어집니다.

리눅스 파티션 확장하기

사용중인 파티션의 크기를 변경하는 방법이 몇가지 되는데요 그 중 하나 resize 를 해 보겠습니다.

테스트 환경은 제 컴퓨터의 Hyper-V 위에 설치된 Ubuntu 입니다.
Clonezilla를 사용하였습니다.
(GParted가 더 편하겠지만… 받아둔 것이 Clonezilla 뿐이여서… 쩝)

아래 이미지 순서대로

  1. 가상 하드 편집해서 크기를 늘렸습니다.
  2. 부팅을 CD에서 하도록 하고 Clonezilla를 마운트 했습니다.
  3. Shell로 들어가서 CLI 툴로 작업합니다.
  4. parted에 디스크를 지정해서 실행합니다.
  5. 남은 공간을 확인해 봅니다.
    BS는 2번 파티션을 확장할 예정입니다.
  6. resize를 하면 뭐라고 하기 때문에 그냥 resizepart로 파티션만 수정하고 종료했습니다.
  7. 다시 CLI에서 파일 시스템 검사를 한번 하고
  8. resize2fs 로 마무리 합니다.
  9. shutdown -r now 한 뒤 디스크 용량을 확인해 보니 잘 확장되었습니다.

런타임에 언마운트 가능한 파티션이라면 언마운트 하고 나서 하셔도 됩니다.

만약 위처럼 보기 좋게 되어 있지 않다면… 조금 수고스럽지만 move를 해서 이리 저리 좀 옮겨서 작업해야 합니다.
BS는 확장이 필요한 파티션을 끝에 배치해서 필요하면 그때 그때 조금씩 늘려서 사용하고 있습니다.

Hypver-V나 VMWare, 아니면 AWS와 같은 환경이라면 용도에 따라 아예 분리된 스토리지를 설정하는 것이 좋습니다.
OS 용, Swap용, Data용, Log 용… 그리고 위와 같은 방법으로 필요시 확장하시면 됩니다.

보너스!!! 파티션 축소하기

  1. fsck 먼저 하고
  2. resize2fs로 줄이고
  3. parted로 resizepart 하면… 끝

참고 자료
[GParted]
[Clonezilla]
[Resize Partition and Filesystemwith fdisk and resize2fs]

Apache2로 간단한 로드밸런싱 하기

딱히 설명이 필요없는 간단 설정

  1. 아파치 모듈 설치
  2. 모듈 활성화
  3. 사이트 파일 수정
  4. 재시작
a2enmod proxy
a2enmod proxy_ajp
a2enmod proxy_balancer
a2enmod proxy_connect
a2enmod proxy_html
a2enmod proxy_http
a2enmod rewrite
a2enmod deflate
a2enmod headers
a2enmod ssl
a2enmod lbmethod_bybusyness
a2enmod xml2enc
vim /etc/apache2/sites-enabled/000-default.conf
apache2ctl configtest
apache2ctl restart

사이트 설정 파일 예제

<Proxy balancer://backend>
         BalancerMember  http://app1.example.com keepalive=On
         BalancerMember  http://app2.example.com keepalive=On

         ProxySet lbmethod=bybusyness
</Proxy>
<VirtualHost *:443>
         SSLEngine               On
         SSLCertificateFile      /etc/apache2/my.cert
         SSLCertificateKeyFile   /etc/apache2/my.key

         ProxyPreserveHost       On
         ProxyRequests           Off

         <LocationMatch ^/.*>
                 ProxyPass balancer://backend
                 ProxyPassReverse balancer://backend
         </LocationMatch>

         ErrorLog ${APACHE_LOG_DIR}/error.log
         CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost> 

  • backend 라는 이름의 밸런서 설정
  • 가상 호스트 *:443에
    • SSL 인증서 설정
    • 프록시 설정
    • 특정 Location (예제에서는 모든 경로)에 프록시 설정

svn+ssh 사용시 private key 설정 방법

아직도 Subversion을 사용하냐 하시는 분이 계실지도 모르지만…
서버 클라이언트 구조에서 svn만큼 명확한 scm이 없죠?
물론 상용 소프트웨어는 많이 있지만요.

본론으로 들어가서
svn+ssh://user@svn.example.com/some/path 를 사용할 때에 매번 패스워드 입력하는 것도 귀찮고
자동화에 써먹을 수 없으니 방법을 찾아 봤습니다.

SVN_SSH=”ssh -i /path/to/key_file”
export SVN_SSH

이러면 CLI 도구인 svn을 사용해서 svn+ssh 를 사용할 수 있습니다.
응용한다면 원격지와의 네트워크 상황이 안 좋다면 압축 옵션을 추가하면 좋겠군요.

그런데 svn+ssh 로 사용해야 할 Host가 2개에 private key 파일이 다르다면???

~/.ssh/config 파일에 아래 내용 추가
Host svn.example.com
IdentityFile /path/to/key_file
User user

이렇게 하면 되지요
이 방법 마음에 드십니까?
더 자세한 정보는 ssh_config manpage 참고

init.d 스크립트 예제

Ubuntu 를 기준으로 살펴 보겠습니다.

/etc/init.d/ 경로에 보면 skeleton 이란 파일이 있습니다.

이 파일을 기본으로 해서 수정을 하시면 됩니다.

[Ubuntu 14.04 LTS skeleton]

여기서 required-xxx 에 쓰이는 virtual facility name 은 아래와 같은 것이 있고, 사용자가 입력한 이름도 비슷한 방법으로 사용할 수 있습니다.

  • $local_fs
  • $network
  • $named
  • $portmap
  • $remote_fs
  • $syslog
  • $time
  • $all
#! /bin/sh
### BEGIN INIT INFO
# Provides:          mongod
# Required-Start:    $remote_fs $syslog $time
# Required-Stop:     $remote_fs $syslog $time
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: MongoDB Data
# Description:       MongoDB service for Sharding
### END INIT INFO

# Author: BS

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="MongoDB"
NAME=mongod
DAEMON=/usr/bin/mongod
DAEMON_ARGS="-f /etc/mongodb/mongod.conf"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
	# Return
	#   0 if daemon has been started
	#   1 if daemon was already running
	#   2 if daemon could not be started
	start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
		|| return 1
	start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
		$DAEMON_ARGS \
		|| return 2
	# Add code here, if necessary, that waits for the process to be ready
	# to handle requests from services started subsequently which depend
	# on this one.  As a last resort, sleep for some time.
}

#
# Function that stops the daemon/service
#
do_stop()
{
	# Return
	#   0 if daemon has been stopped
	#   1 if daemon was already stopped
	#   2 if daemon could not be stopped
	#   other if a failure occurred
	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
	RETVAL="$?"
	[ "$RETVAL" = 2 ] && return 2
	# Wait for children to finish too if this is a daemon that forks
	# and if the daemon is only ever run from this initscript.
	# If the above conditions are not satisfied then add some other code
	# that waits for the process to drop all resources that could be
	# needed by services started subsequently.  A last resort is to
	# sleep for some time.
	start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
	[ "$?" = 2 ] && return 2
	# Many daemons don't delete their pidfiles when they exit.
	rm -f $PIDFILE
	return "$RETVAL"
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
	#
	# If the daemon can reload its configuration without
	# restarting (for example, when it is sent a SIGHUP),
	# then implement that here.
	#
	start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
	return 0
}

case "$1" in
  start)
	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
	do_start
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  stop)
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
	do_stop
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  status)
	status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
	;;
  #reload|force-reload)
	#
	# If do_reload() is not implemented then leave this commented out
	# and leave 'force-reload' as an alias for 'restart'.
	#
	#log_daemon_msg "Reloading $DESC" "$NAME"
	#do_reload
	#log_end_msg $?
	#;;
  restart|force-reload)
	#
	# If the "reload" option is implemented then remove the
	# 'force-reload' alias
	#
	log_daemon_msg "Restarting $DESC" "$NAME"
	do_stop
	case "$?" in
	  0|1)
		do_start
		case "$?" in
			0) log_end_msg 0 ;;
			1) log_end_msg 1 ;; # Old process is still running
			*) log_end_msg 1 ;; # Failed to start
		esac
		;;
	  *)
		# Failed to stop
		log_end_msg 1
		;;
	esac
	;;
  *)
	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
	exit 3
	;;
esac

:

 

참고 자료
[LSBInitScripts – Debian Wiki]

SSL private key 의 passphase 제거

StartSSL에서 1년 평가판 SSL 인증서를 하나 받았는데요.
Private Key에 Passphase가 걸려있어서 걍 썼더니…
웹서버가 뜨면서 암호를 묻는 황당 당혹 난감 신경질 나는 상황이 벌어져버렸네요.
이거 뭐 전문 엔지니어도 아니고 날림으로 걍 찾아서 그때 그때 해결하다보니…
이런 것도 이제는 기억이 안나는군요.


openssl rsa -in <원본 private key 파일> -out <결과를 저장할 파일>

단 한 줄이면 되는 것을… 쩝

Ubuntu Timezone 설정

/etc/timezone을 수정하면 되지요…


근데… 귀찮은데…


sudo dpkg-reconfigure tzdata


이렇게 하면 쉽죠…


그리고 나서는 최소한  cron 대몬은 재시작을 해야죠


service cron restart


혹시 cron 말고 일정 시간에 맞춘 다른 커스텀 서비스가 있으면 함께 재시작…


BS는 이것도 귀찮아 shutdown -r now … ㅋ

우분투 망가진 부트로더 복구

[누엔 블로그 포스트]

여기를 참고하세요.

딱 중요한 포인트는

  1. 라이브 CD로 부팅
  2. 설치한 파티션을 마운트
    mount /dev/linux_partition /mnt
  3. 마운트된 파티션의 dev 디렉토리를 /dev로 바인딩
    mount –bind /dev /mnt/dev
  4. 마운트된 파티션의 proc 디렉토리를 /proc로 바인딩
    mount –bind /proc /mnt/proc
  5. 마운트한 경로를 chroot로 root 경로로 변경
    chroot /mnt
  6. grub-install 로 부트로더 재설치
    grub-install /dev/target_partition
    exit
    umount /mnt/dev
    umount /mnt/proc
    umount /mnt
    shutdown -r now

참 쉽죠잉?

Ubuntu 12.04를 13.04로 바꾸는 방법

  1. 13.04 설치 CD/DVD를 통해서 업그레이드를 설치
  2. Ubuntu의 업데이트 관리자를 통해서 설치
    update-manager -d

2의 방법으로 설치할 경우 한번에 13.04로 업그레이드 되지 않습니다.
12.10부터 해서 한단계식 업그레이드 해야 합니다.

update-manager가 GTK 문제로 불가능 할 경우에는

sudo apt-get install update-manager-core
sudo do-release-upgrade

를 해서 진행하면 됩니다.