2015. 4. 21. 17:07



[SQL]

SELECT *
  FROM
      (
       SELECT A.OWNER
            , A.TABLE_NAME
            , B.COMMENTS AS TABLE_NAME_CO
            , C.COLUMN_ID
            , C.COLUMN_NAME
            , D.COMMENTS AS COLUMN_NAME_CO
            , C.DATA_TYPE || CASE WHEN C.DATA_TYPE IN ('VARCHAR2','CHAR')          THEN ' (' || C.CHAR_LENGTH || ' Byte)'
                                  WHEN C.DATA_TYPE = 'NUMBER' AND C.DATA_SCALE > 0 THEN ' (' || C.DATA_PRECISION ||','|| C.DATA_SCALE ||')'
                                  WHEN C.DATA_TYPE = 'NUMBER' AND C.DATA_SCALE = 0 THEN ' (' || C.DATA_PRECISION ||')'
                                  ELSE C.DATA_TYPE END AS DATA_TYPE
            , C.NULLABLE
            , (SELECT POSITION
                 FROM ALL_CONS_COLUMNS Y
                    , ALL_CONSTRAINTS Z
                WHERE Y.OWNER           = Z.OWNER
                  AND Y.TABLE_NAME      = Z.TABLE_NAME
                  AND Y.CONSTRAINT_NAME = Z.CONSTRAINT_NAME
                  AND Z.CONSTRAINT_TYPE = 'P'
                  AND Y.OWNER           = A.OWNER
                  AND Y.TABLE_NAME      = A.TABLE_NAME
                  AND Y.COLUMN_NAME     = C.COLUMN_NAME) AS COL_PK
            , C.DATA_DEFAULT AS COL_DEFAULT
         FROM ALL_TABLES       A
            , ALL_TAB_COMMENTS B
            , ALL_TAB_COLUMNS  C
            , ALL_COL_COMMENTS D
        WHERE A.OWNER       = B.OWNER
          AND A.TABLE_NAME  = B.TABLE_NAME
            AND C.OWNER       = A.OWNER
          AND C.TABLE_NAME  = A.TABLE_NAME
          AND D.OWNER       = A.OWNER
          AND D.TABLE_NAME  = A.TABLE_NAME
          AND D.COLUMN_NAME = C.COLUMN_NAME
      )
 WHERE OWNER LIKE '%'
   AND TABLE_NAME LIKE '%'
 ORDER BY TABLE_NAME, COLUMN_ID



엑셀 문서작업 한다고 필요해서 작업했던 것인데 나중에 또 써먹을 것 같아서 보관...



Posted by 해비
2015. 4. 17. 15:07




요구사항:

예) 외출 시간이 10:00 ~ 14:00 인 경우, 원래 4시간 이나, 점심시간 (12:00 ~ 13:00) 이 포함되면 해당 범위만큼 제외한 시간을 산정하도록 한다.


입력은 분단위 환산된 정수 값이다.


한계)

- 당일 시간단위의 계산에 한함. 일자가 변경되는 것 까지 고려하지는 않는다.


        /* -----------------------------
         * 2015.04.17
         * Haebi, http://haebi.kr
         * ----------------------------- */
        /// <summary>
        /// 특정 시간간격을 제외한 총 분단위 간격을 구한다.
        /// </summary>
        /// <param name="fromMin">시작분</param>
        /// <param name="toMin">종료분</param>
        /// <param name="exFromMin">제외시작분</param>
        /// <param name="exToMin">제외종료분</param>
        /// <returns></returns>
        private int checkDurMinutes(int fromMin , int toMin, int exFromMin, int exToMin)
        {
            if (toMin < fromMin) throw new Exception("checkDurMinutes() : 종료시간이 시작시간보다 작을 수 없습니다.");
            if (exToMin < exFromMin) throw new Exception("checkDurMinutes() : 제외종료시간이 제외시작시간보다 작을 수 없습니다.");

            /**
             * 제외시킬 기간과 겹쳐질수 있는 4가지 케이스에 대하여 처리하고 있으며,
             * 해당없는 경우(겹쳐지지 않는경우) 그냥 to - from 처리로 끝난다.
             */
            int _retMin = 0;

            try
            {
                // -----<------|---------------|------>------
                if (fromMin <= exFromMin && toMin >= exToMin)
                {
                    _retMin = toMin - fromMin - (exToMin - exFromMin);
                }
                // ------------|---<------>----|-------------
                else if (fromMin >= exFromMin && toMin <= exToMin)
                {
                    _retMin = 0;
                }
                // ------<-----|---------->----|-------------
                else if ((fromMin <= exFromMin)
                    && (toMin >= exFromMin && toMin <= exToMin))
                {
                    _retMin = exFromMin - fromMin;
                }
                // ------------|----------<----|------>------
                else if ((fromMin >= exFromMin && fromMin <= exToMin)
                    && toMin >= exToMin)
                {
                    _retMin = toMin - exToMin;
                }
                // ---<----->--|---------------|-------------
                // ------------|---------------|---<----->---
                else
                {
                    _retMin = toMin - fromMin;
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }

            return _retMin;
        }




그리고 검증을 위한 테스트 코드

               int min1 = 600; // 10:00
                int min2 = 630; // 10:30
                int dmin = 0;

                for (int i = 0; i < 300;i++)
                {
                    min2++; dmin = checkDurMinutes(min1, min2, 720, 780); printLog(i + 1, dmin, min1, min2);
                }



printLog() 부분

        private void printLog(int count, int dmin, int min1, int min2)
        {
            // 테스트 결과 출력 (단위:분)
            // 테스트 넘버    from ~ to 기간    from 분    to 분
            textBox3.Text = textBox3.Text + "\r\n" + count.ToString() + "\t"
                + string.Format("{0:D2}", (dmin / 60)) + ":" + string.Format("{0:D2}", (dmin % 60))
                + "\t" + string.Format("{0:D2}", (min1 / 60)) + ":" + string.Format("{0:D2}", (min1 % 60))
                + "\t" + string.Format("{0:D2}", (min2 / 60)) + ":" + string.Format("{0:D2}", (min2 % 60));
        }

- textBox3 하나 추가해 주면 된다.




테스트 결과(샘플)

카운트 - (외출)시간 - 시작시간 - 종료시간

88    01:58    10:00    11:58
89    01:59    10:00    11:59
90    02:00    10:00    12:00

91    02:00    10:00    12:01
92    02:00    10:00    12:02
93    02:00    10:00    12:03

...(생략)
148    02:00    10:00    12:58
149    02:00    10:00    12:59
150    02:00    10:00    13:00

151    02:01    10:00    13:01
152    02:02    10:00    13:02
153    02:03    10:00    13:03

- 1분단위로 종료시간을 더해가면서 실제 반영되는 시간이 얼마인지를 확인 한다.

- 테스트는 720(12:00) ~ 780(13:00) 까지의 범위에 대해 계산을 하지 않는 것으로 설정하였다.




Posted by 해비
2015. 4. 10. 09:41

Datatable 사용해서 처리하는 구문이 있었는데 의도하지 않은 방향으로 흘러가 버렸네요...


일단 의도는 다음과 같습니다.


1. 테이블에서 Select 하여 대상 데이터를 선택합니다.

2. 원 테이블을 클리어 시킵니다.

3. 선택된 데이터를 집어 넣습니다.



위 의도대로 아래와 같이 코드를 작성하였습니다

            // 테이블 정의
            DataTable srcDT = new DataTable();
            srcDT.Columns.Add("A1");
            srcDT.Columns.Add("A2");
            srcDT.Columns.Add("A3");
            srcDT.Columns.Add("A4");

            // 데이터 입력
            srcDT.Rows.Add(new object[] { "AAA", "111", "A11", "1AA" });
            srcDT.Rows.Add(new object[] { "BBB", "222", "B11", "1BB" });
            srcDT.Rows.Add(new object[] { "CCC", "333", "C11", "1CC" });

            // 커밋
            srcDT.AcceptChanges();

            // 쿼리
            DataRow[] fDR = srcDT.Select("A1 like '" + "A" + "%'");

            srcDT.Clear();
            foreach (DataRow dr in fDR)
            {
                srcDT.Rows.Add(dr);
            }

            for (int i = 0; i < srcDT.Rows.Count; i++)
            {
                textBox1.AppendText(srcDT.Rows[i][0].ToString() + " | "
                    + srcDT.Rows[i][1] + " | "
                    + srcDT.Rows[i][2] + " | "
                    + srcDT.Rows[i][3] + " | " + "\r\n");
            }


이 소스코드가 잘 돌아갈 것 같이 보입니까?



여기에는 치명적인 문제가 있습니다.

원 테이블을 클리어 시켜 버렸다는 것.


선택된 목록만을 가져오기 위해서 Clear 후 다시 선택된 값을 집어 넣고 있지만...;;


정작 빈 껍데기 row만 들어갑니다.


Select 할 때, 값을 복사해 오는것이 아니고 해당 데이터의 위치주소 값을 가져오는 듯 합니다.

그래서, 테이블 클리어 때 값이 다 지워졌고, 해당 주소값의 row를 다시 추가해 봤자 이미 다 지워진 빈 데이터 만 추가될 뿐이고...




이런 경우 제가 찾은 해결책은 2가지 입니다.


1번째는 목록을 not like 로 가져 온 다음, 해당 하는 행을 remove 로 지워 나가는 것.

2번째는 like 로 가져온 행을 새 테이블에 넣어주는 방법 (넣기 전에 원 테이블이 Clear 되면 안됩니다.)



1번째 소스코드

            // 쿼리
            DataRow[] fDR = srcDT.Select("A1 not like '" + "A%" + "%'");

            //srcDT.Clear();
            foreach (DataRow dr in fDR)
            {
                srcDT.Rows.Remove(dr);
            }

            for (int i = 0; i < srcDT.Rows.Count; i++)
            {
                textBox1.AppendText(srcDT.Rows[i][0].ToString() + " | "
                    + srcDT.Rows[i][1] + " | "
                    + srcDT.Rows[i][2] + " | "
                    + srcDT.Rows[i][3] + " | " + "\r\n");
            } 




2번째 소스코드

            // 쿼리
            DataRow[] fDR = srcDT.Select("A1 like '" + "A" + "%'");

            //srcDT.Clear();
            DataTable srcDT2 = new DataTable();
            srcDT2 = srcDT.Clone();
            foreach (DataRow dr in fDR)
            {
                srcDT2.Rows.Add(dr.ItemArray);
            }

            for (int i = 0; i < srcDT2.Rows.Count; i++)
            {
                textBox1.AppendText(srcDT2.Rows[i][0].ToString() + " | "
                    + srcDT2.Rows[i][1] + " | "
                    + srcDT2.Rows[i][2] + " | "
                    + srcDT2.Rows[i][3] + " | " + "\r\n");
            }






Posted by 해비
2015. 4. 5. 20:09

Tor WiFi Router 만들기

WiFi 접속만으로 Tor Network 에 연결할수 있는 라우터를 만들어 보겠습니다.


준비물

- Raspberry pi 본체 (또는 linux OS가 설치된 시스템)

- USB WLAN(RTL8188CUS) 무선랜

  (여기서는 iptime의 N100mini 를 사용했습니다만 동일 칩셋이 들어간 어떤 무선랜이라도 상관없을 것이라 봅니다)

- SD(Raspbian OS) 라즈비안OS가 설치된 SD 메모리 (기타 저장장치에 linux 가 설치된 시스템이면 필요없음)


결과물

- Tor WiFi AP 토르 네트워크에 연결되는 와이파이 액세스 포인트



Tor 이 무엇인지, 어디에 쓰이는지 모르시는분들은 검색해서 참조하여 주십시오.

(양파 모양의 아이콘을 띄고 있습니다.)




[작업순서]

1. AP가 될 무선랜 어뎁터의 IP 설정

2. DHCP서버 설치 및 설정

3. 무선랜을 AP로 변신시켜줄 hostapd 설치 및 설정

4. rtl871xdrv 가 포함된 hostapd 를 다운로드 하여 덮어쓰자

5. tor 설치 및 설정

6. iptables 설정

7. 로그 파일 생성 및 설정

8. Tor 자동시작 설정




1. AP가 될 무선랜 어뎁터의 IP 설정

sudo vim /etc/network/interfaces

1

2

3

4

 iface wlan0 inet static

 address 192.168.42.1

 netmask 255.255.255.0

 up iptables-restore < /etc/iptables.ipv4.nat




2. DHCP서버 설치 및 설정

 # sudo apt-get install isc-dhcp-server

- DHCP 서버 설치



sudo vim /etc/dhcp/dhcpd.conf

1

2

3

4

5

6

7

8

9

10

11

12

 #option domain-name "example.orWg";

 #option domain-name-servers ns1.example.org, ns2.example.org;

 authoritative;

 subnet 192.168.42.0 netmask 255.255.255.0 {

 range 192.168.42.10 192.168.42.50;

 option broadcast-address 192.168.42.255;

 option routers 192.168.42.1;

 default-lease-time 600;

 max-lease-time 7200;

 option domain-name "local";

 option domain-name-servers 8.8.8.8, 8.8.4.4;

 }

- 진하게 표시된 부분에 유의하여 설정을 진행합니다.




 # sudo vim /etc/default/isc-dhcp-server

1

 INTERFACES="wlan0"

- DHCP를 적용할 장치를 설정합니다.



 # sudo service isc-dhcp-server restart

- DHCP 서버 재시작




3. 무선랜을 AP로 변신시켜줄 hostapd 설치 및 설정

 # sudo apt-get install hostapd

- hostapd 설치



sudo vim /etc/hostapd/hostapd.conf

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

 interface=wlan0

 #driver=nl80211

 driver=rtl871xdrv

 ssid=onionWiFi

 hw_mode=g

 ieee80211n=1

 wmm_enabled=1

 wmm_ac_bk_cwmin=4

 wmm_ac_bk_cwmax=10

 wmm_ac_bk_aifs=7

 wmm_ac_bk_txop_limit=0

 wmm_ac_bk_acm=0

 wmm_ac_be_aifs=3

 wmm_ac_be_cwmin=4

 wmm_ac_be_cwmax=10

 wmm_ac_be_txop_limit=0

 wmm_ac_be_acm=0

 wmm_ac_vi_aifs=2

 wmm_ac_vi_cwmin=3

 wmm_ac_vi_cwmax=4

 wmm_ac_vi_txop_limit=94

 wmm_ac_vi_acm=0

 wmm_ac_vo_aifs=2

 wmm_ac_vo_cwmin=2

 wmm_ac_vo_cwmax=3

 wmm_ac_vo_txop_limit=47

 wmm_ac_vo_acm=0

 channel=6

 macaddr_acl=0

 auth_algs=1

 ignore_broadcast_ssid=0

 wpa=2

 wpa_passphrase=yourpassword

 wpa_key_mgmt=WPA-PSK

 wpa_pairwise=TKIP

 rsn_pairwise=CCMP

- 1. AP의 장치명을 설정.

- 3. AP의 드라이버명을 지정.

- 4. SSID 에 노출될 명칭

- 6. n 모드 지원

- 7 ~ 27. WMM (무선 QoS) 설정

- 28. 사용할 무선랜 채널

- 30~36. 무선보안 설정



# sudo vim /etc/default/hostapd

1

 DAEMON_CONF="/etc/hostapd/hostapd.conf"

- hostapd.conf 파일위치 설정




4. rtl871xdrv 가 포함된 hostapd 를 다운로드 하여 덮어쓰자

1

 # wget http://www.adafruit.com/downloads/adafruit_hostapd.zip 

2

 # unzip adafruit_hostapd.zip 

3

 # sudo mv /usr/sbin/hostapd /usr/sbin/hostapd.ORIG 

4

 # sudo mv hostapd /usr/sbin

5

 # sudo chmod 755 /usr/sbin/hostapd




5. tor 설치 및 설정

 # sudo apt-get install tor 

- tor 설치



sudo vim /etc/tor/torrc

1

2

3

4

5

6

7

8

 Log notice file /var/log/tor/notices.log

 VirtualAddrNetwork 10.192.0.0/10

 AutomapHostsSuffixes .onion,.exit

 AutomapHostsOnResolve 1

 TransPort 9040

 TransListenAddress 192.168.42.1

 DNSPort 53

 DNSListenAddress 192.168.42.1

- 7, 8 IP주소는 위에서 설정한 wlan0 의 것과 동일하게 합니다.




6. iptables 설정

 iptables -P INPUT ACCEPT

 iptables -F


 iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

 iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

 iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP


 iptables -A INPUT -i lo -j ACCEPT


 iptables -A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT


 iptables -A INPUT -i eth0 -p udp --sport 68 --dport 67 -j ACCEPT


 iptables -A INPUT -i wlan0 -j ACCEPT


 iptables -A INPUT -i eth0 -p tcp -m tcp --sport 137 --dport 137 -j ACCEPT

 iptables -A INPUT -i eth0 -p udp -m udp --sport 137 --dport 137 -j ACCEPT

 iptables -A INPUT -i eth0 -p udp -m udp --sport 138 --dport 138 -j ACCEPT

 iptables -A INPUT -i eth0 -p tcp -m tcp --sport 139 --dport 138 -j ACCEPT


 iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


 iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

 iptables -P INPUT DROP


 iptables -P OUTPUT ACCEPT


 iptables -nL

 

 iptables -t nat -F

 iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 22 -j REDIRECT --to-ports 22

 iptables -t nat -A PREROUTING -i wlan0 -p udp --dport 53 -j REDIRECT --to-ports 53

 iptables -t nat -A PREROUTING -i wlan0 -p tcp --syn -j REDIRECT --to-ports 9040

 iptables -t nat -nL

- eth0 포트 22 는 ssh 접속용, 67~68 은 dhcp, 137~139 는 netbios (RFC 1001, 1002 문서 참고)

- wlan0 의 포트 리다이렉트 설정은 ssh 접속용인 22번을 제외하고 tor 라우터 설정.




1

 # sudo iptables-save > iptables.conf

2

 # sudo cp iptables.conf /etc/iptables.conf

- 부팅 후 iptables 규칙이 유지되도록 현재 규칙을 저장



sudo vim /etc/network/interfaces

1

 pre-up iptables-restore < /etc/iptables.conf

- eth0 설정 아랫부분에 위 내용 추가




7. 로그 파일 생성 및 설정

1

 # sudo touch /var/log/tor/notices.log

2

 # sudo chown debian-tor /var/log/tor/notices.log

3

 # sudo chmod 644 /var/log/tor/notices.log




8. Tor 자동시작 설정

1

 # sudo service tor start

2

 # sudo service tor status

3

 # sudo update-rc.d tor enable



ls -l /var/log/tor 

- tor 로그를 확인할 수 있다.




웹브라우저를 열고 아래 주소에 접속하면 Tor 네트워크에 연결되었는지를 확인할 수 있다.

https://check.torproject.org



만약 위 화면과 다르게 양파에 붉은 X 자 표시가 되어있다면, Tor 네트워크로 접속되지 않았음을 의미한다.




[변경사항]

- 2015.04.22 : iptables 설정 중 deny 로그 남기는 부분의 설정 위치에 대한 오류가 있어 정정합니다.






[참고사이트]

http://www.maketecheasier.com/set-up-raspberry-pi-as-wireless-access-point/

http://www.raspberrypi.org/forums/viewtopic.php?t=53943&p=413909

http://www.raspberrypi.org/forums/viewtopic.php?f=28&t=44044

https://learn.adafruit.com/onion-pi/install-tor

http://www.instructables.com/id/Raspberry-Pi-Tor-relay/step1/Start-the-TOR-Server/

http://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf






Posted by 해비
2015. 3. 21. 11:29

라즈베리파이 CPU 속도 확인

pi@raspberrypi ~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
600000
pi@raspberrypi ~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
600000
pi@raspberrypi ~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
900000
 


cur : 현재 속도

min : 최저 속도

max : 최고 속도


라즈베리파이2 는 클럭 미 설정 시 600~900 MHz 로 동작하나 보네요...






[참고]

http://www.raspberrypi.org/forums/search.php?keywords=cur_freq






Posted by 해비
2015. 3. 21. 10:03


이 글은 OpenVPN 을 설치 하여 모든 트래픽을 VPN서버로 우회 하여 사용하는 것을 목적으로 설명합니다.


서버로 Rasbian (Raspberry Pi), 클라이언트는 iOS 의 OpenVPN App을 사용했습니다.

(안드로이드에도 구글 플레이스토어에 동일한 앱이 있습니다)



[진행 순서]

1. 서버 설치

2. 인증서 생성

3. 서버 설정

    3-1. server.conf

    3-2. conf 파일명 설정

4. 클라이언트 접속설정

5. 연결

6. 마무리 작업

7. 방화벽 설정 [추가 2015.04.10]




('#'은 root 권한을 의미 합니다.)


1. 서버 설치

# sudo apt-get install openvpn






2. 인증서 생성

1

 # cp /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn

2

 # cd /etc/openvpn

3

 # source vars

4

 # ./clean-all

5

 # ./build-ca

6

 # ./build-key-server server

7

 # ./build-key haebi

8

 # ./build-dh


- 1. 필요한 설정파일들을 /etc/openvpn 으로 복사합니다.

- 2. 현재 워킹 디렉토리 이동

- 3. 인증서 생성에 필요한 환경변수 등록

- 4. 새로 생성할 것이므로 /etc/openvpn/keys 의 내용을 모두 제거 (진행 중 잘못된 경우에 필요함)

- 5. CA 인증서 생성. (대충 엔터키만 눌러주시면 됩니다)

- 6. 서버 인증서 생성. (엔터키 눌러주다가 y? 라고 묻는 부분에 반드시 y 입력 후 엔터. y는 2번 물어봅니다.)

- 7. 사용자 인증서 생성. (OpenVPN에 접속할 사용자 수 만큼 생성합니다.)

- 8. 디피헬먼 암호화를 위한 키 생성


추후 사용자 인증서가 추가로 필요한 경우, [3번]과 [7번]을 반복해 주시면 되겠습니다.

4번 ./clean-all 해서 다 날려버리면 처음부터 다시 작업 & 기존 사용자의 인증서까지 무효가 됩니다. <-- 조심!!






3. 서버 설정

3-1. server.conf

1

 # cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/

2

 # gunzip server.conf.gz


- 1. 서버 설정파일을 /etc/openvpn 으로 복사.

- 2. 압축해제



# vim server.conf

1

 port 1194

2

 proto udp

3

 dev tun

4

 ca /etc/openvpn/keys/ca.crt

5

 cert /etc/openvpn/keys/server.crt

6

 key /etc/openvpn/keys/server.key  # This file should be kept secret

7

 dh /etc/openvpn/keys/dh1024.pem

8

 server 10.8.0.0 255.255.255.0

9

 push "route 10.8.0.0 255.255.255.0"

10

 push "redirect-gateway def1"

11

 push "dhcp-option DNS 10.8.0.1"

12

 push "dhcp-option DNS 168.126.63.1"


- 1. 포트설정

- 2. 프로토콜 설정 tcp 또는 udp 중에서 선택

- 3. tun 디바이스 사용. (tap 도 있는데 차이점은 모르겠다. 그냥 디폴트로 이거 쓰자)

- 4. CA 인증서 경로 지정

- 5. 서버 인증서 경로 지정

- 6. 서버 개인키 경로 지정

      (이 파일은 비밀리에 지켜져야 한다. 라고 되어있죠? 유출되지 않도록 각별히 신경을 써 줍니다^^)

- 7. 디피헬먼 키 경로 지정

- 8. VPN 서버가 사용할 IP 대역 설정

- 9. 라우팅 경로 설정

     (VPN서버 네트워크의 상위 레벨에 여러 서브넷이 존재하는 경우, 여기서 등록해줘야 접근이 가능한가 봅니다.)

- 10. 패킷의 리 다이렉션 설정. (중요!)

     (이 옵션이 있으면 접속된 클라이언트의 모든 트래픽이 VPN을 거쳐 갑니다. 인터넷은 기존연결로 가고 내부 망 접속만 하고자 한다면 설정하지 않습니다.)

- 11 ~ 12. DNS 설정입니다.

      (모든 패킷을 리다이렉션 하는 경우에, 12번 라인이 없으면 인터넷이 안됩니다. 12번의 DNS 주소는 꼭 저 주소일 필요는 없습니다. 사용하는 다른 DNS 주소가 있다는 그것을 기입합니다.)




3-2. conf 파일명 설정

# vim /etc/default/openvpn

1

 AUTOSTART="openvpn"


- 1. openvpn config 파일명이 openvpn 임을 /etc/init.d/openvpn 에게 알려줍니다.

     ( 이제 /etc/init.d/openvpn start 하게 되면, /etc/openvpn/openvpn.conf 파일을 찾아서 읽게 됩니다.)



# mv server.conf openvpn.conf

- config 파일명을 변경하여 준다.



서버시작

# /etc/init.d/openvpn restart


- 만약 서버 로그가 보고 싶다면, stop 시키고 아래의 명령을 실행하면 실시간 로그를 확인할 수 있습니다.

openvpn --config /etc/openvpn/openvpn.conf 






4. 클라이언트 접속설정

# cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn

- 클라이언트 접속 설정 샘플을 복사합니다.



# vim /etc/openvpn/client.conf

1

 client

2

 dev tun

3

 proto udp

4

 remote 0.0.0.0 1194

5

 ca ca.crt

6

 cert haebi.crt

7

 key haebi.key


- 1. client 모드임을 의미. (서버 설정파일에는 server 이라고 되어있다)

- 2. tun 디바이스 사용

- 3. udp 프로토콜 사용

- 4. 서버 접속 주소, 포트 설정 (0.0.0.0 대신 서버 IP나 도메인을 적는다)

- 5. ca 인증서 파일명 설정

- 6. 사용자 인증서 파일명 설정

- 7. 사용자 개인키 파일명 설정


2~4번 항목은 서버와 동일하게 설정해야 합니다.

5번은 서버의 ca 인증서와 동일한 것이어야 합니다.


현재 클라이언트 설정에 필요한 Key의 위치

 /etc/openvpn/keys/ca.crt

 /etc/openvpn/keys/haebi.crt

 /etc/openvpn/keys/haebi.key

 /etc/openvpn/client.conf






5. 연결

앱스토어에 OpenVPN 으로 검색하면 어플이 나옵니다.

제작자가 OpenVpn Technologies 라고 된것으로 다운 받습니다.




iTunes 에 연결 후, OpenVPN 앱의 도큐먼트에 4개 파일을 넣어줍니다.

ca.crt

haebi.crt

haebi.key

client.ovpn


(client.ovpn 은 client.conf 파일명을 변경한 것 입니다)


앱을 실행하면 + 버튼이 생기고 눌러서 추가하면 저 4개 파일이 사라지면서 설정이 추가 됩니다.


인 / 아웃 용량까지 제공하므로, 간에 데이터 사용량 측정? 도 가능하겠군요~호호호...(???)


팁 한가지 : 서버측 말고 클라이언트 측 로고를 볼수 있는 방법... 조기 위에 Connected 옆에 우측에 꺽쇠괄호 보이죠?

저거 누르면 클라이언트측 로그가 주욱~~~ 나옵니다




연결은 됐는데 인터넷이 안되면...?

NAT설정, ipforward 설정이 필요하다.


NAT 설정

# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE


ipforward 허용 설정

# vim /etc/sysctl.conf

 net.ipv4.ip_forward=1






6. 마무리 작업

이 설정을 재부팅 시에도 그대로 될수 있도록 하겠다.

openvpn은 알아서 시작하는데 nat 설정이 날아가 버려서 문제가 되었다.


그래서 찾아본 해결책이 외국 포럼에서 본것으로 iptables-save 로 현재 상태를 저장하고, 부팅시 불러오는 방법


# iptables-save > /etc/iptables.conf 

- 일단 현재 nat 상태를 저장한다.



# vim /etc/network/interfaces

 iface eth0 inet dhcp

    pre-up iptables-restore < /etc/iptables.conf

- eth0 바로 아래부분에 iptables-restore 를 적용해 준다.






7. 방화벽 설정

iptables를 활용하여 방화벽 규칙을 적용한다. [추가 2015.04.10][변경1 2015.04.22]

iptables -P INPUT ACCEPT
iptables -F

iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP


iptables -A INPUT -i lo -j ACCEPT


iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT


iptables -A INPUT -p tcp -m tcp --dport 1194 -j ACCEPT



iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT



iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
iptables -P INPUT DROP


iptables -P OUTPUT ACCEPT


iptables -nL



iptables -t nat -F
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
iptables -t nat -nL

- 차단된 접속시도는 /var/log/syslog 에 "iptables denied:" 으로 시작하는 로그가 쌓이게 된다.

- iptables -nL, iptables -t nat -nL 은 현재 규칙을 화면에 표시하여 주는 역할을 한다.

- INPUT (들어오는) 규칙은 기본적으로 DROP (갖다버림) 이며, -j ACCEPT 에 명시된 항목만 허용한다.



부팅시 이 방화벽 규칙을 유지 시키기 위해서 아래 작업을 추가한다.

# sudo iptables-save > iptables.conf

# sudo cp iptables.conf /etc/



#sudo vim /etc/network/interfaces

 auto lo

iface lo inet loopback
iface eth0 inet dhcp
pre-up iptables-restore < /etc/iptables.conf

- eth0 아래에 iptables-restore 명령으로 방화벽 규칙을 적용 시켜준다.






[변경사항]

- 2015.04.22 : iptables 설정 중 deny 로그 남기는 부분의 설정 위치에 대한 오류가 있어 정정합니다.






[참고]

https://www.debian-administration.org/article/445/Getting_IPTables_to_survive_a_reboot

http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/System_management/VPN/OpenVPN

https://openvpn.net/index.php/open-source/documentation/howto.html


openvpn.net 의 링크에서 Routing all client traffic (including web-traffic) through the VPN 항목을 찾아 보면

모든 트래픽 보내기에 대한 설정 예시와 함께 상세한 설명이 있다.





Posted by 해비
2015. 3. 15. 23:59


비트 연산자


&

 AND 연산

|

 OR 연산

^

 XOR 연산

~

 비트 반전 0 <-> 1

<<

 왼쪽으로 비트열 이동

>>

 *오른쪽으로 비트열 이동

* 음수의 경우 오른쪽으로 비트열 이동시 MSB가 바뀌어지는 경우가 있으므로 주의.




AND 연산

둘 다 1이면 1, 그렇지 않으면 0



OR 연산

둘 중 하나가 1이면 1, 둘다 0이면 0



XOR 연산(*)

다르면 1, 같으면 0



~ 연산

0 이면 1, 1이면 0




이게 뭐 ? 라고 생각할 수도 있겠지만...

간단히 말하자면 1 Byte 공간을 예로 들면 1 Byte = 8 Bit 이다.


예를들어 저 8개의 0 또는 1 조합을 이용하면, 우리는 8개의 True / False 값을 저장하는 변수를 단지 1 Byte 로 해결 볼 수 있다는 의미이다.





Posted by 해비
2015. 3. 15. 23:24



초기화 하지 않은 변수의 값을 출력하면 쓰레기 값이 출력된다고 알고 있었는데...


vs2013 에서는 변수가 초기화 되지 않았다고 빌드 자체를 거부한다.

1>------ Build started: Project: ex211, Configuration: Debug Win32 ------

1>  ex211.c

1>d:\vs2013\ex211\ex211\ex211.c(10): error C4700: uninitialized local variable 'num2' used

1>d:\vs2013\ex211\ex211\ex211.c(10): error C4700: uninitialized local variable 'num1' used

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

 




<< 소스코드 >>

#include <stdio.h>

int main(void)

{


int num1;

int num2;


printf("%d %d", num1, num2);


return 0;

} 

- 초기화 하지 않은 변수 num1, num2를 사용하는 소스코드




vs2013 에서 확인된 내용인데... 다른 컴파일러에서는 어찌 반응할지 찾아봐야 겠다.


직접 시도 안해 봤으면 그냥 예전 지식 그대로 알고 있을 뻔 한 사건;;


역시 직접 부딪혀 보는게 최고~!!




Posted by 해비
2015. 3. 9. 11:59




파일 읽기 - 라인단위, 텍스트 파일

#include <iostream>
#include <fstream>

using namespace std;

int main(void)
{
    ifstream ifile;

    char line[200]; // 한 줄씩 읽어서 임시로 저장할 공간
       
    ifile.open("input.txt");  // 파일 열기

    if (ifile.is_open())
    {
        while (ifile.getline(line, sizeof(line))) // 한 줄씩 읽어 처리를 시작한다.
        {
            cout << line << endl; // 내용 출력
        }
    }

    ifile.close(); // 파일 닫기

    return 0;
}




파일 쓰기 - 라인단위, 텍스트 파일

#include <iostream>
#include <fstream>

using namespace std;

int main(void)
{
    ofstream ofile;
    ofile.open("output.txt");

    // 파일 쓰기
    for (int x = 0; x < 10; x++)
    {
        ofile << x << endl;
    }

    ofile.close(); // 파일닫기

    return 0;
}







Posted by 해비
2015. 2. 24. 15:52

텍스트 상자 라던가...


여튼 입력 항목이 많을 때에는 컨트롤 배열로 선언해서 다루면 여러모로 편리합니다. ^__^

가끔 써먹어야 하는데 기억이 가물가물 해서 정리를...

 


전역변수 선언

        TextBox[] tBox; // 컨트롤 배열로 사용할 TextBox 전역변수 선언

        const int ARR_TEXTBOX_COUNT = 20; // 생성할 텍스트 박스 갯수 설정 



컨트롤 배열 생성, 기본 옵션 설정, 이벤트 연결

        private void CreateTextBoxes()

        {

            tBox = new TextBox[ARR_TEXTBOX_COUNT];


            for (int i = 0; i < tBox.Length; i++)

            {

                // 새 인스턴스 생성

                tBox[i] = new TextBox();


                // 기본옵션 설정

                tBox[i].Name = "txt" + i.ToString(); // 텍스트상자에 이름을 부여한다. 예) txt1

                tBox[i].Text = "";

                tBox[i].Width = 32;

                tBox[i].Height = 21;

                tBox[i].Tag = i.ToString();


                // 그룹박스에 텍스트상자 추가, 각 그룹박스당 10개씩 생성한다.

                if(i < 10)

                {

                    groupBox1.Controls.Add(tBox[i]);

                }

                else

                {

                    groupBox2.Controls.Add(tBox[i]);

                }


                // 이벤트 등록

                tBox[i].KeyPress += Form1_KeyPress;

            }



이벤트 처리

        // 키눌림 이벤트 처리

        void Form1_KeyPress(object sender, KeyPressEventArgs e)

        {

            // 엔터 키 입력

            if(e.KeyChar == (char)13)

            {

                // 이벤트가 발생한 컨트롤의 핸들 얻기

                TextBox hTextBox = (TextBox)sender;


                // 컨트롤 번호 얻기

                int ctrlNum = Convert.ToInt32(hTextBox.Tag);


                // 마지막 박스에서는 다음으로 이동하지 않는다. (오류방지)

                if(ctrlNum < ARR_TEXTBOX_COUNT -1)

                {

                    tBox[ctrlNum + 1].Focus();

                }

            }

        } 



텍스트 상자 이름 한번에 가져오기

        // 모든 텍스트 상자의 이름 가져오기!!

        private void getControlNames(Control control)

        {

            // 대상 control 의 하위에 있는 모든 컨트롤을 대상으로 스캔한다.

            foreach (Control tmpCtrl in control.Controls)

            {

                // 재귀호출 : 컨트롤이 또 다른 컨트롤을 품고 있으면 하위의 끝까지 스캔한다.

                if (tmpCtrl.Controls.Count > 0)

                    getControlNames(tmpCtrl);


                // 현재 스캔중인 컨트롤이 TextBox 형식이면...

                if (tmpCtrl is TextBox)

                {

                    TextBox textBox = (TextBox)tmpCtrl; // TextBox 으로 형 변환 한다.


                    txtLog.AppendText(textBox.Name.ToString() + "\n"); // 현재 컨트롤 이름 Log 추가

                }

            }

        }




vs2013 에서 작성한 예제 소스 첨부


ControlArrayExample.rar




예제 실행 화면



Posted by 해비