Mac의 svn에서 프로젝트 Import

sudo svn import -m “설명” 프로젝트폴더 SVN주소 —force-log
ex)sudo svn import -m “KoreataxiClient” KoreataxiClient http://localhost/svn/LixingSVN/KoreataxiClient —force-log

Tomcat서버를 Root가 아닌 일반사용자로 80포트를 서비스 하는 경우

문제점

Linux(혹은 Unix)에서는 1024번 이하의 포트가 보안상의 이유로 root권한을 가지고 있는 로세스만이 포트를 선점할 수 있다.(root reserved ports) root계정이 아닌 일반계정으로 Tomcat을 서비스 할 때, 정상적으로 Tomcat의 리스너(Listener)가 동작하지 않음을 TOMCAT LOG(logs/catalina.out)
통하여 확인 할 수 있다.

 

2009. 12. 15 오후 4:14:31 org.apache.coyote.http11.Http11Protocol init
심각: Error initializing endpoint
java.net.BindException: Permission denied<null>:80

 

따라서 일반계정으로 Tomcat 80번 포트(HTTP 기본포트)에서 서비스 하려 한다면, Tomcat HTTP Connector Port 1024이상의 포트번호로 지정해준 뒤80포트로의 모든 인바운딩을 Tomcat HTTP Connector Port로 리다이렉트 해주어야한다아래는 iptables 명령을 이용한 간단한 예제이다.(반드시 root권한으로 수행되어야 한다.)

 

우선 8080포트가 리슨을 하고있는지 확인한다.

# netstat -ntl

The output will look something like

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State
tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN
tcp        0      0 ::ffff:127.0.0.1:8005       :::*                        LISTEN
tcp        0      0 :::8009                     :::*                        LISTEN
tcp        0      0 :::8080                     :::*                        LISTEN
tcp        0      0 :::22                       :::* 

예제

TOMCAT 서버가 구동되는 호스트의 IP : 211.110.33.86 또는 localhost
TOMCAT 서버의 HTTP Connector Port : 8080

iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -I OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 8080

위의 예제는 현재 서버(211.110.33.86) 8080포트에 대한 모든 인바운딩을 80 포트로 리다이렉트(REDIRECT)하는 명령이다.

 

또는 다음과 같이 명령을 입력한다.

# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

 

Run the folloing command to verify that redirect is working fine

# iptables -t nat -L

The output will look something like

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             anywhere            tcp dpt:http redir ports 8080

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

 Run the following command to remove the routing

# iptables -t nat -D PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

 Remember, when you are modifying your running configuration of iptables, you will still need to save your changes in order for it to persist on reboot. Be sure to test your configuration before saving it with “service iptables save” so that you don’t lock yourself out

 

생각해보아야할 문제

root권한으로 TOMCAT과 같은 WAS를 구동하였을때 발생 할 수 있는 문제점은?
WEB SERVER없이 TOMCAT과 같은 WAS만으로 서비스하였을때 발생 할 수 있는 문제점은?
SSL(https)의 경우 443번 포트를 해당 프로토콜의 기본 포트로 사용하는데, SSL도 이와같은 처리를 해주어야할까?

redis replication 구성 및 haproxy를 통한 서비스

1. 서비스 개요

redis의 서비스 장애을 극복하기 위하여 redis를 이중화 하여 구성한다. 보통 마스터 1개에 여러 슬래이브로 구성을 하고
redis 서비스를 감시하는 Sentienl을 여러게 두어, redis 마스터 서비스 장애시 슬레이브중 하나를 자동으로 마스터로 승격시켜
장애가 없는 서비스 구성이 가능하다. 또한 라우터 스위칭을 담당하는 haproxy를 최상단에 두어 redis sendinel에서 변경한
redis 마스터 포토를 자동으로 감지 이를 서비스를 해줌으로서, redis-client에서는 서비스포트 변경없이 원활한 서비스가 가능하다.

2. redis replication 구성

redis의 환경설정을 통하여 포트별로 master/slave구성을 한 뒤, 해당서비스를 감시하는 sentinel를 설정하여
운영한다.

2.1 redis master/slave 구성
첫번째로 redis를 설치를 한다. 해당내용은 여기 블로그 Ubuntu 에 Redis 컴파일, 빌드및 서비스 환경구성
를 참조한다.
기본적으로 설치된 /etc/redis/redis.conf 설정파일 복사해서 여러포트로 운영할 경우, 쉽게 서비스구분을 위해
redis_<서비스포트>.conf로 파일명을 변경하여 구성한다.

– 기본구성
conf파일에서 서비스 접속보안을 위해 항목중 requirepass 를 설정한다. 또한 서비스 장애시 Sentinel에 의해 redis서버가 master에서 slave로
강등될 수 있기 때문에 masterauth 도 동일안 인증번호로 설정한다.

requirepass "pass1234"
masterauth "pass1234"

– slave 구성
기본구성된 conf파일을 copy하여 서비스할 포트만 변경한다. 포트를 변경후, slave에서는 대상 master를 설정하는
항목만 입력하면 된다.

# slaveof  
slaveof localhost 6379

– slave 서비스 자동시작
기존 구성된 master의 /etc/initd.d/redis_<서비스포트> 파일을 카피한 후 편집하면 된다.
내용중 서비스 할 포트만 변경하고, 주의할 점은 시비스 종료설정 부분에서 현재 redis서비스가 인증번호를 설정한 후, 가동하게 되면
서비스 종료시 반드시 인증번호를 입력애야 처리된다.
기본으로 제공한 서비스 재시작 스크립트에서 해당 내용을 반영하여 저장한다.
굵게 표시된 부분을 추가하면 된다.

...
stop)
        if [ ! -f $PIDFILE ]
        then
            echo "$PIDFILE does not exist, process is not running"
        else
            PID=$(cat $PIDFILE)
            echo "Stopping ..."
            $CLIEXEC -p $REDISPORT -a pass1234 shutdown
            while [ -x /proc/${PID} ]
            do
                echo "Waiting for Redis to shutdown ..."
                sleep 1
            done
            echo "Redis stopped"
        fi
        ;;
...

– 서비스 확인
redis 를 접속하거나 테스트할수 있는 redis-cli를 이용하여 현재 서비스 되고 있는 master 및 slave를 확인한다.
우선 마스터 확인을 하여 굵게 표시된 항목이 나나타는지 확인한다.

moram:/etc/redis$ redis-cli -p 6379 -a pass1234
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=431055865,lag=1
master_replid:369d2a1176cf484f172c62b4ea0fe95a27d39a69
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:431055998
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:430007423
repl_backlog_histlen:1048576
127.0.0.1:6379> 

redis 슬레이브도 마찬가지로 굵게표시된 부분을 확인한다.

moram:/etc/redis$ redis-cli -p 6380 -a pass1234
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:431067009
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:369d2a1176cf484f172c62b4ea0fe95a27d39a69
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:431067009
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:430018434
repl_backlog_histlen:1048576

2.2 redis sentinel 구성
redis의 서비스를 모니터링 한후, 서비스 장애시, 자동으로 master를 변경해주는 redis sentinel의 구성은
인증번호와 대성마스터 서버의 정보만 변경하여 사용하면 된다.
redis설치 후, 자동적으로 sentinel.conf파일이 만들어 지며 해당 내용을 변경한다. 환경설정 항목중 기본으로
설정되어진 이름은 mymaster이며 redis설치시 설정한 인정정보를 동일하게 등록하면 된다.

# Default is 30 seconds.
sentinel monitor mymaster 127.0.0.1 6379 1
sentinel down-after-milliseconds mymaster 5000
sentinel auth-pass mymaster pass1234

3. haproxy 구성
redis서비스 포트 앞에 haproxy를 두어서 로드발렌싱을 처리할 수 있으며, haproxy설정을 통하여 자동적으로 redis서비스
master/slave가 변경될 경우, 장애없이 원활하게 서비스 할 수 있도록 구성할 수 있다.
보통 haproxy가 설치되면 환경설정 파일은 /etc/haproxy/haproxy.conf 에 있으며, 해당 파일을 구성하여 운영한다.
특별히 주의할 점은 앞에서 redis replication 구성시 인증번호를 설정하는 부분을 추가하면 된다.

frontend mosaic_ft_redis
        bind *:6378 name redis
        default_backend mosaic_bk_redis

backend mosaic_bk_redis
        option tcp-check
        tcp-check connect
        tcp-check send AUTH\ pass1234\r\n
        tcp-check expect string +OK
        tcp-check send PING\r\n
        tcp-check expect string +PONG
        tcp-check send info\ replication\r\n
        tcp-check expect string role:master
        tcp-check send QUIT\r\n
        tcp-check expect string +OK
        server redis_6379 localhost:6379 check inter 1s
        server redis_6380 localhost:6380 check inter 1s

Xcode에서 앱스토어에 업로드할때 Unsupported architectures [x86_64, i386] 에러에 대한 대체

터미널로 프로젝트 폴더에 가서 lipo 명령으로 Carthage 폴더에 있는 라이브러리별로 i386, x86_64 에 대하여 제거한다.

lipo -remove i386 ./Carthage/Build/iOS/SQLite.framework/SQLite -o ./Carthage/Build/iOS/SQLite.framework/SQLite
lipo -remove x86_64 ./Carthage/Build/iOS/SQLite.framework/SQLite -o ./Carthage/Build/iOS/SQLite.framework/SQLite

제거되었는지 확인해 본다.

lipo -info ./Carthage/Build/iOS/SQLite.framework/SQLite

Raspberry Pi3 부팅시 자동으로 Python으로 짠 프로그램 실행

윈도우 서비스처럼 부팅시 라즈베리파이 로그인을 안하고 자동으로 올라오게 하려고 한다.

1. 프로그램을 실행할 쉘 스크립트 작성

vi mBizOkHub.sh 
sudo /usr/bin/python3.5 /home/pi/mBizOkHub/mBizOkHub.py /home/pi/mBizOkHub/config.ini & 

2. 권한부여

chmod 755 mBizOkHub.sh

3. /etc/rc.local 파일의 하단에 /home/pi/mBizOkHub/mBizOkHub.sh 를 추가

sudo vi /etc/rc.local 

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

/home/pi/mBizOkHub/mBizOkHub.sh

exit 0

mac에 cordova(PhoneGap)을 이용한 IOS용 간단한 inapp brower 만들기

1. cordova(PhoneGap)을 이용하기 위해서는 nodejs를 설치해야된다.
https://nodejs.org 에 접속하여 최신 nodejs를 설치한다.

2. nodejs를 이용하여 cordova를 설치한다
mac에서 터미널을 이용 다음을 입력하여 cordova를 설치한다

sudo npm install -g cordova

3. mac에서 작업할 폴더위치를 생성한다 임시로 workspace로 정함

4.mac터미널에서 해당 작업폴더로 이동한 후, cordova를 이용하여 신규프로젝트를
생성한다. com.moramcnt.mosaicadm라는 ID의 mosaicadm라는 프로젝트 생성

cordova create mosaicadm com.moramcnt.mosaicadm "MosaicAdmin"

5. xcode용 프로젝트 자동생성을 위하여 platform 명령을 사용하여 생성한다.
생성된 디렉토리로 이동하여 터미널로 다음을 입력한다.

cordova platform add ios

6. in app 브라우저를 위해서 플러그인을 설치한다.
기본적으로 특정외부 url로 이동하게 되면 ios에서는 safari브라우저를 이용하여 이동하게 된다.
이를 생성된 앱안에서 이동하게끔 하려면 inappbrowser 플러그인을 설치해야된다.
생성된 디렉토리로 이동하여 터미널로 다음을 입력한다.

cordova plugin add cordova-plugin-inappbrowser

7. app가동시 특정 url로 바로 접속하기 위해서 index.html파일을 변경한다.
생성된 디렉토리의 www/index.html 파일이 있다 이를 변경한다.
해당 url은 네이버 모바일 홈으로 임시 지정한다.

<!DOCTYPE html>
<html>
  <head>
    <title>moram admin</title>
    <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
    <script type="text/javascript" charset="utf-8">
    document.addEventListener("deviceready", onDeviceReady, false);
    function onDeviceReady() {
        // external url
        var ref = window.open(encodeURI('http://m.naver.com'), '_blank', 'location=no,toolbar=no');
    }
    </script>
  </head>
  <body>
  </body>
</html>

8. 아이콘및 앱 가동시 초기로딩 화면(splash) 파일을변경한다.
초기 디폴트 아이콘은 cordova로 지정된 디폴트 아이콘밖에 없다 이를 변경하기 위하여 다음을 처리한다.
8-1. imagemagick을 설치한다.
변경을 위해서는 imagemagick 라는 프로그램이 필요로 한데.
home-brew라는 프로그램이 필요하다 이를 먼저설치힌다.
터미널을 이용하여 다음을 입력한다.

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

imagemagick을 설치한다.

brew install ghostscript imagemagick

8-2. 아이콘 자동배포및 splash의 자동배포를 위해서는 cordova-icon, cordova-splash nodejs를 통하여
각각 설치힌다. 터미널을 통하여 다음을 입력한다.

npm install -g cordova-icon cordova-splash

8-3. 변경할 아이콘 및 초기로딩 파일을 프로젝트 루트에 등록
생성된 디렉토리로 이동후 지정할 아이콘및 splash파일은 png 파일 중 싸이즈가 가장 큰 파일을
icon.png, splash.png로 각각 이름을 변경하여 등록한다.

8-4. cordova-icon cordova-splash를 실행하여 각각 필요한 싸이즈에 맞는 이미지를 자동등록 한다.
생성된 디렉토리로 이동후 cordova의 명령어를 이용하여 cordova-splash, cordova-icon 을 입력한다.

cordova-splash
cordova-icon

9. ios프로젝트에 신규변경된 항목들을 적용한다.
index.html파일이나 config.xml파일 및 이미지들이 변경될 경우, 해당 데이터를 적용시키기 위하여
다음과 같은 명령을 입력한다.
생성된 디렉토리로 이동후 cordova명령어를 입력한다.

cordova prepare ios

10. 생성된 프로젝트로 이동하여 xcode로 프로젝트를 로드한다.
해당 platform 폴더로 이동하여 프로젝트를 더블클릭한다.

11. xcode 프로젝트에서 특정폰에 빌드하기 위해서 Singnig정보를 설정한다.
설정할 Singnig 파일이 없을경우 생성은 다른 구글링을 통하여 알아본다.

12. xcode에서 컴파일 하여 확인 한다.

CORS (Cross-origin resource sharing) 서비스가 다른 크로스도메인 해결방법

Ajax에서 특정 서비스 호출 시 도메인이 서로 다를경우, 정상적인 서비스를 호출하기 위해서는 Spring MVC의 필터링을 이용하여 처리할 수 있다.

1. OncePerRequestFilter 를 상속 필터 클레스 구현

package 패키지명;

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;

public class CorsFilter extends OncePerRequestFilter {

	@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        response.addHeader("Access-Control-Allow-Origin", "*");
        if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())); {
            // CORS "pre-flight" request
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers", "Authorization");
            response.addHeader("Access-Control-Max-Age", "1728000");
        }
        filterChain.doFilter(request, response);
    }
}

2. web.xml에 필터로 설정

  
      corsFilter
      패키지.CorsFilter 
  
  
      corsFilter
      /data/*