2016년 12월 28일 수요일

fail2ban ip 영구 차단

엄청 간단하다.

/etc/fail2ban/jail.conf 중 bantime = -1(영구차단)로 설정

 

예전에는 아마도 fail2ban 재시작시 banip가 없어지게끔 되어 있었나보다.

현재는 (Fail2ban v0.9.5) sqlite에 DB로 저장 되어 있기 때문에 다른 설정이 필요치 않다.

다만 재시작 시 로딩이 조금 느리다..




sqlite 파일 위치
[root@df log]# fail2ban-client get dbfile
Current database file is:
`- /var/lib/fail2ban/fail2ban.sqlite3

table 확인
[root@df log]# sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 .table
bans fail2banDb jails logs

차단된 명령어는 bans란 테이블에 들어가 있다. 그중에 ip값만 가져오면 차단된 ip 목록을 확인 가능하다.
중복된 것도 있기 때문에 distinct를 사용한다.
[root@df log]# sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 "select distinct ip from bans;"
1.206.220.154
1.31.67.224
1.34.190.13
101.25.28.112
103.243.107.193
103.243.54.168
104.43.161.37
...

ps.
테스트 서버에 findtime = 60, maxretry = 3 으로 설정 하고 ssh 포트를 기본포트(22)로 변경 하고 났더니, 하루에 100개이상의 공격이 들어온다... ㅎㄷㄷ;

2016년 12월 21일 수요일

다버튼 마우스 구매시 주의사항

레이저 나가 같은 마우스는 정말 사용하기 쉽지 않은 다버튼 마우스이다.



 

엄지 손사락을 아주 살포시 잡아야 하기 때문이다.

지금 마우스를 쓰고 있다면 엄지를 잡지 않고 마우스를 써봐라.

그러면 나가 같은 다버튼 마우스가 얼마나 똥망인줄 알게 될 거다.

 

최종적으로 구입한건 nyth 마우스 커스텀으로 버튼을 넣을 수 있어서

엄지를 넣을 수 있게, 6,7,10,11번 버튼을 빼고 사용중이다.

크게 마음에 들지는 않지만...

아무튼...

 
다버튼 마우스를 고를 때, 엄지 손가락 부분에 버튼을 가져다 넣은 것들은 전부 제끼자.

2016년 12월 15일 목요일

mysql(mariadb) 테이블별 mysqldump 백업

디비별 디렉토리를 만들고, 테이블별 .sql 파일을 만든다.
[root@localhost cron.daily]# vim sqlBackup.sh 
#!/bin/bash

_DB_PASS='password'
_BACKUP_DIR='/backup/sqlBackup/'

find $_BACKUP_DIR* -mtime +7 -exec rm -fr {} \; > /dev/null 2>&1

db_list=`echo "show databases;" | mysql -N -uroot -p${_DB_PASS}`
eval `date "+day=%d; month=%m; year=%Y"`

INSTD="$_BACKUP_DIR/sql-backup-$year-$month-$day"
mkdir -p $INSTD

for db in $db_list; do
if [ ! -d $INSTD/$db ]
then
mkdir $INSTD/$db
fi
table_list=`echo "show tables" | mysql -N -uroot -p${_DB_PASS} $db`
for table in $table_list; do
mysqldump -uroot -p${_DB_PASS} --lock-all-table --opt --quick --quote-names $db $table > $INSTD/$db/${table}.sql
done
done

2016년 12월 12일 월요일

L2 스위치에서 포트 매핑

MRTG의 생성 할 때 골치 아픈 것중에 하나가 스위치의 각 포트별 서버가 어떤 서버인가 하는 것이다.

보통 MRTG는 스위치의 포트에 걸기 때문이다. 서버에 snmp를 설치하여 만들 수도 있지만, 서버의 접근 권한이 없는 경우도 많기 때문이다.

신입시절에는 그냥 랜선을 눈을 따라가서, 하나씩 기록하고 그걸로 등록하곤 했다.
이게 너무 불편한게 일단 IDC를 가야되고, 혼자서는 스위치와 서버에 연결된 랜선이 어떤 건지 확인하기가 매우 어렵다. 두명은 같이 가야 확인이 용이하다.

 

포트매핑 프로그램을 알고 나서는 한결 편해졌다. L2와 L3 스위치의 snmp 만 알면 L2스위치의 몇번 포트에 몇번 IP 가 할당되어 있는 지 바로 확인이 가능하기 때문이다.

그런데 이번에 L3 스위치가 없는 네트워크 작업이 있었다. L3가 없는 건 아니지만 IDC 소유라 접근 권한이 없다.

네트워크 작업은 L2 스위치를 교체한 것인데, 시스코의 2950 모델이다.
이것저것 알아보다 보니 스위치에서 'sh arp' 명령어가 가능 했다.

L2 스위치는 mac-address-table만 있는 줄 알았는데, 그게 아니였다.
그럼 역시 간단 하다.
arp 테이블(sh arp)의 mac과 mac-addres-table(sh mac-addres-table)의 mac 값을 비교하면 어느 포트가 어떤 아이피를 가지고 있는 지 알 수 있다.

포트 매핑 프로그램에 L3부분과 L2 부분을 같은 L2 스위치를 넣고 비교할 수도 있다.
L2의 arp 테이블에는 대개 자신의 IP와 게이트웨이에 IP 밖에 없을 것이다.
왜냐면 같은 네트워크 대역에 대해서는 물어봐 주는 사람이 없기 때문이다. 자신의 IP는 고정이라 제외하고, 포트에 물린 서버들은 통신할 때, 게이트웨이만 찾기 때문이다. 대개 외부로 나가는 연결일 것이다.

생각해보니 매핑 프로그램에서  L3란게 의미를 가지는 게 아니라 그 스위치가 게이트웨이 역할을 하기 때문에 의미가 있는 것 같다.

 

arp 테이블에 내가 원하는 서버의 IP를 넣어보자.

L2스위치에서 찾으려고 하는 서버의 IP에 핑을 날려보자. 그리고 arp 테이블을 확인 하면 IP가 등록되어 있을 것이다. 하위단의 서버에서 ping을 날려도 L2스위치에 등록된다.
문제는 ping을 막아 놓은 곳도 많은 게 문제인데, 이럴 때는 telnet을 이용해 보자. ping을 막아 놓은 서버가 웹서버라면 80포트는 열렸을 것이다.
telnet SERVER_IP 80

해당 서버에 연결이 되었다.
그리고 다시 arp 테이블 확인하면 역시 등록이 되었다.

스위치 포트별 서버의 IP를 체크하기 위해 직접 랜선을 일일이 비교하는 작업은 안해도 된다.

2016년 12월 8일 목요일

이벤트 실패 로그에 있는 공격 IP 뽑아내기.

이벤트 로그에 지속적인 공격이 들어오는 게 보인다. ㅅㅂㄹㄷ

이벤트 로그를 한개 한개 뒤져서 체크 하기가 힘들다.

예전에 작성했던 자동 차단 파워쉘을 조금 수정해서 목록만 뽑도록 만듬.

원격데스크탑(RDP)

###################### Config ######################

#아래의 형식으로 있는 IP 주소를 가져오기 위한 정규식
$regex2 = [regex] "원본 네트워크 주소:\t(\d+\.\d+\.\d+\.\d+)";

#아래 값 이상인 것만 차단 리스트($blacklist)에 추가
$deny_count = 5

#이벤트 로그가 많을 경우 어마무시하게 오래 걸림. 불러올 로그 개수
$newest = 1000

###################### Config ######################

##최종 공격자 IP 배열
$blacklist = @();

#초기화
$list=""

#메인 명령어( 이 스크립트의 코어임.)
#이벤트 실패 로그인 4625 ID 에서 아이피가 있는 message 부분에서 IP만 뽑아낸다.
#list 변수 = 이벤트 실패 로그 아이피 (중복포함)
$ips = get-eventlog Security -Newest $newest | Where-Object {$_.EventID -eq 4625 } | foreach {
$m = $regex2.Match($_.Message); $ip = $m.Groups[1].Value; $ip;
} | Sort-Object | Tee-Object -Variable list | Get-Unique
# ($list | Select-String 211.217.48.254 -SimpleMatch | Measure-Object).count;

foreach ($forIp in $ips) {
#로그인 실패 이벤트 로그 중에는 IP가 없는 것들도 있는 데, 그런 경우
#빈값이 들어오므로 continue로 넘겨준다.
if([string]::IsNullOrEmpty($forIp))
{
#'continue';
continue;
}
if (-not ($blacklist -contains $forIp)) {
$attack_count = ($list | Select-String $forIp -SimpleMatch | Measure-Object).count;
"Found RDP attacking IP on 3389: " + $forIp + ", with count: " + $attack_count;
if ($attack_count -ge $deny_count) {$blacklist = $blacklist + $forIp;}
}
}
""
"========$deny_count 회 이상 실패 IP==============="
#방화벽 등록 명령어를 이용해서 자동 차단으로 해도 된다.
$blacklist

 

MSSQL
로그 예제 : 사용자 'sa'이(가) 로그인하지 못했습니다. 원인: 암호가 제공된 로그인의 암호와 일치하지 않습니다. [클라이언트: 211.41.41.203]

###################### Config ######################

#아래의 형식으로 있는 IP 주소를 가져오기 위한 정규식
$regex2 = [regex] "클라이언트: (\d+\.\d+\.\d+\.\d+)";

#아래 값 이상인 것만 차단 리스트($blacklist)에 추가
$deny_count = 5;

#이벤트 로그가 많을 경우 어마무시하게 오래 걸림. 불러올 로그 개수
$newest = 1000

###################### Config ######################

##최종 공격자 IP 배열
$blacklist = @();

#초기화
$list=""

#메인 명령어( 이 스크립트의 코어임.)
#이벤트 실패 로그인 18456 ID 에서 아이피가 있는 message 부분에서 IP만 뽑아낸다.
#list 변수 = 이벤트 실패 로그 아이피 (중복포함)
$ips = get-eventlog Application -Newest $newest | Where-Object {$_.EventID -eq 18456 } | foreach {
$m = $regex2.Match($_.Message); $ip = $m.Groups[1].Value; $ip;
} | Sort-Object | Tee-Object -Variable list | Get-Unique
# ($list | Select-String 211.217.48.254 -SimpleMatch | Measure-Object).count;

foreach ($forIp in $ips) {
#로그인 실패 이벤트 로그 중에는 IP가 없는 것들도 있는 데, 그런 경우
#빈값이 들어오므로 continue로 넘겨준다.
if([string]::IsNullOrEmpty($forIp))
{
#'continue';
continue;
}
if (-not ($blacklist -contains $forIp)) {
$attack_count = ($list | Select-String $forIp -SimpleMatch | Measure-Object).count;
"Found RDP attacking IP on MSSQL: " + $forIp + ", with count: " + $attack_count;
if ($attack_count -ge $deny_count) {$blacklist = $blacklist + $forIp;}
}
}
""
"========$deny_count 회 이상 실패 IP==============="
#방화벽 등록 명령어를 이용해서 자동 차단으로 해도 된다.
$blacklist

 


언제 한번 날 잡아서 완성형으로 만들어야 될 듯...

2016년 12월 7일 수요일

디렉토리를 심볼릭링크 생성시 여러개가 만들어지는 원인.

디렉토리를 ln -s 명령으로 심볼릭 링크로 만들 때, 두 번 실행시 dest 폴더 안에 원하지 않는 링크가 생긴다.

명령을 두번 실행하면 첫번째 명령에서 만들어진 '심볼릭 링크 디렉토리'안에 또하나의 파일이 생긴다.

세번째부터는 깨진 파일이라도 있으니까 그 아래로는 더 이상 생성되지 않는다.

 

이럴 때는 -n 명령을 써보자

-n 옵션의 설명은 다음과 같다.

-n, --no-dereference
treat LINK_NAME as a normal file if it is a symbolic link to a directory

디렉토리의 심볼릭 링크면 일반 파일로 취급한다고 한다.

 

테스트 해보자.

n 옵션이 없으면 아래와 같이 두번까지 정상 실행되며, 세번째부터 에러가 나온다.
dirSym 으로 들어가 보면 깨진 dirSrc 심볼릭 링크가 만들어져있다.
[root@df tmp]# mkdir dirSrc
[root@df tmp]# ln -s dirSrc dirSym
[root@df tmp]# ln -s dirSrc dirSym
[root@df tmp]# ln -s dirSrc dirSym
ln: failed to create symbolic link `dirSym/dirSrc': 파일이 있습니다

 

dirSym 링크를 지우고 n 옵션을 주고 다시 실행하면 아래와 같이 두번째에 에러가 발생한다.
[root@df tmp]# rm dirSym
rm: remove 심볼릭 링크 `dirSym'? y
[root@df tmp]# ln -sn dirSrc dirSym
[root@df tmp]# ln -sn dirSrc dirSym
ln: failed to create symbolic link `dirSym': 파일이 있습니다

 

 

결론 : 디렉토리를 symbolic link로 만들 때는 n 옵션을 추가해서 만들자.
ln -sn src dest

2016년 11월 29일 화요일

Predictive Failure 란?

HP 서버중 한대에서 디스크 에러가 났다.
physicaldrive 1I:1:7 (port 1I:box 1:bay 7, SAS, 300 GB, Predictive Failure)
physicaldrive 1I:1:8 (port 1I:box 1:bay 8, SAS, 300 GB, OK)

 

Predictive Failure

문구 자체가 참 애매하다. 에러가 난 것도 아니고

에러가 날 거란 걸 예측해 주는 거라는 데, 그 원리가 무엇인지 궁금했다.

 

영문 위키에서 찾을 수 있었다.
he drive firmware compares the measured parameters against predefined thresholds and evaluates the health status of the drive.

드라이브의 측정 된 값과 사전정의 된 임계값과 비교하여 상태를 평가한다고 되어 있다.
 
참고 : http://comfix.kr/162
 

2016년 11월 25일 금요일

logrotate가 안될 때...

오랜만에 서버 점검을 하니 messages 로그가 비정상으로 크다.

무려 1.8G!
-rw-------. 1 root root 1915638280 2016-11-25 09:01 messages

 

접근 시도가 많은 것으로 알고 failer들 차단하고 나섰는 데, 뭔가 이상하다.

로그 파일이 messages밖에 없다. 기본적으로 rotate가 돌아서 messages.1이나

messages-날짜, 이런 형식으로 있어야 되는 데, 없다.

 

rotate가 안되고 있다!!.
 
아래 명령어로 확인. -d 옵션이 debug 모드.
/usr/sbin/logrotate -d /etc/logrotate.conf

출력 내용중 아래와 같이 이상점 발견
considering log /var/log/messages
log needs rotating

로테이트가 필요없다고!? 2G에 육박하고 있는 데 무슨 소리야.

 

logrotate는 /var/lib/logrotate.status 파일의 내용을 참조하여 rotate를 한다.

해당 파일을 살펴보니 내용이 없다.
#비정상(문제서버)
[root@localhost log]# cat /var/lib/logrotate.status
logrotate state -- version 2

#정상(비교대상 서버)
[root@localhost log]# cat /var/lib/logrotate.status
logrotate state -- version 2
"/var/log/yum.log" 2016-1-1
"/var/log/cups/error_log" 2016-10-9
"/var/named/data/named.run" 2016-11-20
"/var/log/sssd/*.log" 2015-1-6
"/var/log/dracut.log" 2016-1-1
"/var/log/wtmp" 2015-1-6
"/var/log/spooler" 2016-11-20
"/var/log/btmp" 2016-11-1
"/var/log/xferlog" 2016-11-20
"/var/log/maillog" 2016-11-20
"/var/log/cups/*_log" 2015-1-6
"/var/log/secure" 2016-11-20
"/var/log/messages" 2016-11-20
"/var/account/pacct" 2015-1-6
"/var/log/cron" 2016-11-20
"/var/log/vsftpd.log" 2015-1-7

 

열심히 검색 했으나, 원인은 찾을 수가 없다.

 

해결법은 아래 명령어로 rotate를 강제 적용 하는 것이다.
/usr/sbin/logrotate -f /etc/logrotate.conf

위와 같이 하면 /var/lib/logrotate.status 내용이 정상 서버와 같이 만들어지고,
아래와 같이 로테이트 된다. 기존 파일을 분할하는 건 아니다.
-rw------- 1 root root 148 2016-11-25 09:58 messages
-rw-------. 1 root root 1915641841 2016-11-25 09:58 messages-20161125

2016년 11월 16일 수요일

PPS cfgmaker

mrtg로 pps 를 체크하는 것에 대해서 글을 썼는데,
cfgmaker로 만들고 그걸 다시 수정하는 게 번거로웠다.

cfgmaker는 perl 로 작성되어 있어서 수정이 가능하다.

그래서 target 관련 부분만 수정해서 ppscfgmaker를 만들었다.

diff로 비교해 보면 알지만 한개 라인만 수정하였다.
[root@localhost bin]# diff cfgmaker ppscfgmaker 
730c730
< my $default_target_directive = "Target[$target_name]: $if_ref:$router_connect";
---
> my $default_target_directive = "Target[$target_name]: ifInUcastPkts.$if_ref&ifOutUcastPkts.$if_ref:$router_connect + ifInNUcastPkts.$if_ref&ifOutNUcastPkts.$if_ref:$router_connect";

ppscfgmaker
확장자가 없으면 업로드가 안되서 .txt를 추가했다.
.txt 부분만 지우고 사용하면 된다.

2016년 11월 9일 수요일

MRTG PPS(packet per second) 설정

MRTG는 기본 BPS 외에 파라미터를 통해서 여러가지 그래프를 그릴 수 있다.

그 중에서 PPS 를 그려보자.

MRTG 사이트를 보면 MIB 리스트가 있는데, 거기에 보면 여러가지 OID 값이 있다.

그 중 패킷 관련 아래의 4가지만 적용한다.
#유니캐스트
ifInUcastPkts
ifOutUcastPkts

#NON 유니캐스트
ifInNUcastPkts
ifOutNUcastPkts

MRTG 적용 방법은 아래 처럼 하면 된다.

기존 cfgmaker 로 생성한 Target 정보를 아래처럼 변경하면 된다.

BPS 적용(cfgmaker 로 생성된 내용.)
Target[SWITCH_pps]: 86:public@111.111.222.222:::::2

PPS 적용
Target[SWITCH_pps]: ifInUcastPkts.86&ifOutUcastPkts.86:public@111.111.222.222:::::2+ ifInNUcastPkts.86&ifOutNUcastPkts.86:public@111.111.222.222:::::2



다른 블로그 글을 보니 ifInUcastPkt 와 ifOutUcastPkts 만 적용하는 하는 글도 보았는데,
여기서는 NON 유니캐스트도 포함시킨 것에 주의 하자.

2016년 11월 8일 화요일

시스코 스위치 로그 날짜 변경 및 ntp 설정

시스코 스위치에서 로그를 볼 때, 날짜 부분이 아래와 같이 UPTIME으로 나오기 때문에 보기에 불편하다.
5w1d: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/5, changed state to down

 

날짜로 변경하자.
#conf t
(config)#service timestamps debug datetime localtime
(config)#service timestamps log datetime localtime

 

아래 명령어로 현재 시간을 확인 가능하다.
#sh clock
*17:26:25.762 UTC Mon Jul 9 2001

시간이 맞지 않는다. ntp 설정을 해주어야 겠다.
(config)#ntp server time.bora.net
Translating "time.bora.net"...domain server (8.8.8.8) [OK]

동기화 상태 확인
#sh ntp status
Clock is synchronized, stratum 3, reference is 203.248.240.140

상태가 unsynchronized 로 나오는 경우가 있는 데, 5분정도 지나서 다시 확인 하면 적용 되어 있다.
time.bora.net 에서 계속해서 요청 못하도록 막은 것 같다.

time.bora.net lookup을 못하면 네임서버 설정을 해 준다.(KT 아이피임.)
(config)#ip name-server 168.126.63.1

2016년 10월 22일 토요일

selinux disabled

selinux 설정파일 위치는 /etc/sysconfig/selinux 로 알고 있었다.

해당 파일에서 SELINUX=disabled 로 변경 시키고 재부팅을 해도 selinux가 disable 되지 않는다.

확인 해 봤더니, 원래 위치는 /etc/selinux/config이고 /etc/sysconfig/selinux 파일은 링크만 걸려 있는 거다.

어떻게 된 일인지 특정 서버만 링크가 아닌 일반 파일이 /etc/sysconfig/selinux 생성되어 있다.

/etc/selinux/config 에서 설정 변경하니 정상적으로 disabled 된다.

파워쉘로 메일 전송 테스트

$From = "fromaddress@domain.com"
$To = "toaddress@domain.com"
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
$Username = "username@gmail.com"
$Password = "gmailpassword"
$subject = "Email Subject"
$body = "Insert body text here"

$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);

$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.Send($From, $To, $subject, $body);

출처

2016년 10월 21일 금요일

파워쉘 실행시 에러

C:\Users\77100606\Downloads\Get-GeoIP.ps1 파일을 로드할 수 없습니다. C:\Users\77100606\Downloads\Get-GeoIP.ps1 파일에 디지털 서명하지 않았습니다. 스크립트가 시스템에서 실행되지 않습니다. 자세한 내용은 "get-help about_signing"을 참조하십시오..
At line:0 char:0

파워쉘 스크립트는 그 권한이 막강하기 때문에 파일마다 디지털 사인은 해야 한다.

그러나 인터넷에 일반사용자 가 사인까지 할리는 만무하다.

해서 그런 스크립트를 싫행 하려면 정책 변경을 해야 한다.
Set-ExecutionPolicy RemoteSigned

Restricted : 파워쉘 실행 정책 기본 값. 명령어 하나씩 실행 가능. 스크립트를 불러와 실행하지 못함
AllSigned : 오직 신뢰된 배포자에 의해 싸인된 스크립트만 실행가능
RemoteSigned : 로컬에서 생성한 스크립트만 실행가능. 다운로드받은 스크립트는 신뢰된 배포자에 의해 싸인된 것만 실행 가능
Unrestricted : 모든 스크립트 실행 가능
ByPass : 아무것도 차단되지 않고 경고나 메시지 없이 실행가능
Undefined : 정책이 적용되지 않음. 기본 정책이 적용됨(Restricted)

출처
출처

2016년 10월 18일 화요일

오라클 접속 안될 시 체크

오라클 클라이언트 설치는 당연한 거겠죠?

 

1.오라클 홈 위치 확인
#윈도우
echo %ORACLE_HOME%

#리눅스
echo $ORACLE_HOME

2.tnsnames.ora 내용 확인(위치 : %ORACLE_HOME%\network\admin\tnsnames.ora)


SERVER_NAME =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = mydomain.com)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ORCL)
)
)


3.tnsping 체크
tnsping alias
ex>tnsping SERVER_NAME

4. sqlplus로 실제 접속 테스트
sqlplus 아이디/패스워드@ALIAS
EX>sqlplus myid/pass@SERVER_NAME

5.tnsnames.ora 내용으로 sqlplus 테스트(tnsnames.ora 내용에서 alias를 뺀 나머지 부분만 한줄로 만들어서 테스트)
sqlplus myid/pass@"(DESCRIPTION =    (ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = mydomain.com)(PORT = 1521)) ) (C
ONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = ORCL) ) )"

MSSQL 에서 오라클로 LINKED SERVER 생성시 오류

MSSQL 에서 오라클로 LINKED SERVER 생성시 오류 발생
연결된 서버 "SERVER_NAME"에 대한 OLE DB 공급자 "OraOLEDB.Oracle"의 인스턴스를 만들 수 없습니다. (Microsoft SQL Server, 오류: 7302)  도움말을 보려면 다음을 클릭하십시오:

이 사이트에서 해결책 확인

오라클 클라이언트 설치 후 SQLSERVER 재시작 해야됨.;;

2016년 10월 12일 수요일

vpopmail(pop3) brute force 공격 차단

qmail vpopmail 을 쓰고 있다.

서버 점검 중 pop3로 접속시도를 하는 로그를 발견했다.

없는 아이디로 계속 시도하는 것과 계정은 있지만 패스워드를 계속 틀리게 입력하는 유형 2가지.
Oct 11 11:27:54 mail vpopmail[27836]: vchkpw-pop3: vpopmail user not found admin12@domain.com:109.104.203.62

Oct 11 15:02:11 mail vpopmail[15277]: vchkpw-pop3: password fail (pass: 'e603f6c507b3993651f0439553584c50') acount@domain.com:110.70.15.59

한두개가 아니라 같은 아이피가 계정만 바꿔서 계속 시도하고 있다.
fail2ban으로 vpopmail 차단을설정하면 좋은데, 실 운영서버라 fail2ban 설치하기가 쉽지 않다.

그래서 스크립트 작성.
#/bin/bash


help()
{
echo ""
echo "/var/log/maillog is default"
echo "iptable apply is not default"
echo "banCount 100 is default"
echo "-a : iptable applied"
echo "-f : maillog FILE PATH"
echo "-c : ban count"
echo ""
echo "Usae : $0 -a -c 100 -f /var/log/maillog "
exit 0
}


ignoreIPs=("222.222.222.222" "111.111.111.111")
maillog="/var/log/maillog"
banCount=100
fw=false


while getopts ac:f: opt
do
case $opt in
a)
fw=true
;;
c)
banCount=$OPTARG
;;
f)
maillog=$OPTARG
;;
*)
help
exit 0
;;
esac
done


banIPs=`grep -E 'user not found|password fail' ${maillog} | awk -F: '{print $NF}' | sort | uniq -dc | awk '{if ($1 > '"${banCount}"') print $NF}'`

for banIP in $banIPs
do
for ignoreIP in ${ignoreIPs[@]}
do
if [ $ignoreIP == $banIP ]
then
# echo "ignore IP: ${ignoreIP}"
# echo "ban IP : $banIP"
break
fi
done

echo "ban IP : $banIP ,whois : $(geoiplookup $banIP)"
if [ $fw = true ] ; then
iptables -A INPUT -s ${banIP}/24 -j DROP
fi

done


if [ $fw = true ] ; then
#remove duplicate iptables rules
#http://www.krazyworks.com/remove-duplicate-iptables-rules/
/sbin/service iptables save
/sbin/iptables-save | awk '!x[$0]++' > /tmp/iptables.conf
/sbin/iptables -F
/sbin/iptables-restore < /tmp/iptables.conf
/sbin/service iptables save
/sbin/service iptables restart
if [ -f /tmp/iptables.conf ] ; then /bin/rm -f /tmp/iptables.conf ; fi
fi


 

1. banCount 는 같은 IP가 해당 값이상일 경우만 가져온다.
실제사용자가 실패할 경우도 있기 때문에 100정도면 적당한 것 같다.

2. ignoreIPs는 차단하지 않을 IP를 적어준다.

3. iptable에 적용하는 데, 중복으로 계속 적용된다.
마지막 부분이 중복을 없애고 다시 설정하는 부분이다.

maillog 파일의 생성을 살펴보면 매일 오전 4시 마다 rotate 되고 있다
cron으로 4시 30분 부터 실행되게끔 걸어주면 되겠다.

2016년 10월 5일 수요일

catalina.out파일에서 system.out.print 내용 확인이 안될 때...

centos7 에서 yum 을 이용해 tomcat을 설치하고

'systemctl stop tomcat.service' 명령어를 이용하여 톰캣을 실행하였다.

catalina.out 파일에서 system.out.print 내용이 쌓이지 않는 것을 확인하였다.

catalina.$DATE.log 파일에도 역시 쌓이지 않는다.

/var/log/messages에 해당 내용이 쌓인다.

명령어는 아래와 같이 사용하면 된다.
journalctl -u tomcat -f
or
tail -f /var/log/messages

참조1
참조2

2016년 9월 29일 목요일

vpopmail 설치시 에러

문경윤(디지문)님이 제작한 스크립트로 설치 중 vpopmail 설치 도중에러 발생.

환경은

centos 6.8 32bit 이며 mysql은

yum install mysql mysql-server

를 통해 'mysql  5.1.73'를 설치



에러 1.

configure: error: Unable to find your MySQL inc dir, specify --enable-incdir.

해결.
yum -y install mysql-devel



에러2.

gcc -I. -I/var/lib/mysql/ -I. -I. -I. -fPIC -g -O2 -Wall -c -o libvpopmail_a-vauth.o `test -f 'vauth.c' || echo './'`vauth.c
vauth.c:33:19: error: mysql.h: 그런 파일이나 디렉터리가 없습니다

해결.

mysql.h 파일은 mysql-devel을 설치하면 만들어지는 데 find 명령으로 찾아보니 그 위치가 /var/user/include/mysql 이다.
[root@localhost src]# find / -name mysql.h
/usr/include/mysql/mysql.h

근데 실제 mysqld은 /var/lib/mysql에 설치되어 있으니 거기서 mysql.h를 찾고 있다. 당연히 없지. 아래의 옵션으로 lib위치를 추가 해 주면 된다.

configure 옵션에 libdir=/var/user/include/mysql 추가

2016년 9월 28일 수요일

centos 7에서 변경 된 것 30가지.

centos 7이 되면서 기존에 사용하던 명령어가 없어져서 난감한 경우가 참 많다.

꽤 많은 부분이 바뀐 것 같다. 그래서 찾아 본 링크

영문임.. OTL

2016년 9월 5일 월요일

네이버 로그인 ASP 버젼 클래스

asp 사이트에서 네이버 로그인 사용 할 일이 생겨서 만들었다.

 

NaverOAuth.asp
<!--#include virtual="/lgdacom/md5.asp" -->
<!--#include virtual="/Class/json2.asp"-->
<%
Class clsNaverOAuth

Private Sub Class_Initialize()
End Sub

private m_clientId
private m_clientSecret
private m_redirectUrl
private m_state
private m_session
private m_code '로그인 인증 요청 API 호출에 성공하고 리턴받은 인증코드값 (authorization code)
private m_refreshToken '갱신 때 필수 - 네이버 사용자 인증에 성공하고 발급받은 갱신 토큰(refresh token)
private m_accessToken '삭제 때 필수 - 기 발급받은 접근 토큰으로 URL 인코딩을 적용한 값을 사용


Public Property Get clientId()
clientId = m_clientId
End Property

Public Property Let clientId(value)
m_clientId = value
End Property


Public Property Get clientSecret()
clientSecret = m_clientSecret
End Property

Public Property Let clientSecret(value)
m_clientSecret = value
End Property


Public Property Get redirectUrl()
redirectUrl = m_redirectUrl
End Property

Public Property Let redirectUrl(value)
m_redirectUrl = value
End Property


Public Property Get state()
state = m_state
End Property

Public Property Let state(value)
m_state = value
End Property


Public Property Get session()
session = m_session
End Property

Public Property Let session(value)
m_session = value
End Property


Public Property Get refreshToken()
refreshToken = m_refreshToken
End Property

Public Property Let refreshToken(value)
m_refreshToken = value
End Property


Public Property Get accessToken()
accessToken = m_accessToken
End Property

Public Property Let accessToken(value)
m_accessToken = value
End Property


Public Property Get code()
code = m_code
End Property

Public Property Let code(value)
m_code = value
End Property

Public Property Get generate_state
Dim rand, mt, state,returnVal
Randomize
rand = Int((999999 * Rnd) + 111111)
mt = Timer
generate_state = md5( mt & rand )
End Property

Public Property Get authQueryString()
authQueryString = "response_type=code"
authQueryString = authQueryString + "&client_id=" + m_clientId
authQueryString = authQueryString + "&redirect_uri=" + Server.URLEncode(m_redirectUrl)
authQueryString = authQueryString + "&state=" + Server.URLEncode(m_state)
End Property

Public Property Get tokenAuthQueryString()
tokenAuthQueryString = "client_id=" + m_clientId
tokenAuthQueryString = tokenAuthQueryString + "&client_secret=" + m_clientSecret
tokenAuthQueryString = tokenAuthQueryString + "&grant_type=authorization_code"
tokenAuthQueryString = tokenAuthQueryString + "&state=" + m_state '발급시
tokenAuthQueryString = tokenAuthQueryString + "&code=" + m_code '발급시
End Property

Public Property Get tokenRefreshQueryString()
tokenRefreshQueryString = "client_id=" + m_clientId
tokenRefreshQueryString = tokenRefreshQueryString + "&client_secret=" + m_clientSecret
tokenRefreshQueryString = tokenRefreshQueryString + "&grant_type=refresh_token"
tokenRefreshQueryString = tokenRefreshQueryString + "&refresh_token=" + m_refreshToken '갱신시
End Property

Public Property Get tokenDeleteQueryString()
tokenDeleteQueryString = "client_id=" + m_clientId
tokenDeleteQueryString = tokenDeleteQueryString + "&client_secret=" + m_clientSecret
tokenDeleteQueryString = tokenDeleteQueryString + "&grant_type=delete"
tokenDeleteQueryString = tokenDeleteQueryString + "&access_token=" + m_accessToken '삭제시
tokenDeleteQueryString = tokenDeleteQueryString + "&service_provider=NAVER" '삭제시
End Property

Public Function httpRequest(url, AuthTkn)
Dim returnDic : Set returnDic = Server.CreateObject("Scripting.Dictionary")
Dim objXMLHTTP : Set objXMLHTTP = server.CreateObject("MSXML2.ServerXMLHTTP")
objXMLHTTP.setOption 2,13056 'ignore SSL errors
objXMLHTTP.Open "POST", url, false
If AuthTkn = "" Then
objXMLHTTP.setRequestHeader "Content-Type", "application/json;charset=UTF-8"
Else
objXMLHTTP.setRequestHeader "Content-Type", "application/xml"
objXMLHTTP.setRequestHeader "Authorization", AuthTkn
End If
objXMLHTTP.Send

If objXMLHTTP.status = 200 Then
'response.write(objXMLHTTP.responseText)
'response.end
Dim jsonstring : jsonstring = objXMLHTTP.responseText
Dim Info : set Info = JSON.parse(join(array(jsonstring)))
Dim key : for each key in Info.enumerate()
returnDic.Add key, Info.get(key)
next
Else
'에러처리
returnDic.Add "error", "status is not 200"
End if

Set httpRequest = returnDic
End Function
End Class

%>

인클루드 파일 설명
md5.asp
stat 값을 생성할 때, asp 자체적으로는 md5 기능이 없어서 추가 했다.
네이버로그인 예제에 해당 기능을 사용하는 데 asp 는 그런 기능이 없다.

해당 사이트가 기존에 사용하고 있는 부분이여서
넣긴 했는데, md5 기능을 빼고 랜덤 함수만 사용하여도
크게 문제는 없을 것 같긴하다.

꼭 사용하려면 asp md5로 검색하면 역시 소스가 잘 나오기 때문에
추가하는데는 어렵지 않을 것이다.

 

json2.asp
네이버 리턴값을 json 으로 주기 때문에 넣어야 한다.
역시 asp 자체적으로 json 파싱기능이 없기 때문이다.

 

사용법
<%@Language="VbScript"%>

<!--#include virtual="/Class/NaverOAuth.asp"-->
<%
Dim NAVER_CLIENT_ID : NAVER_CLIENT_ID = "네이버클라이언트ID"
Dim NAVER_SECRET_KEY : NAVER_SECRET_KEY = "네이버비밀키"
Dim NAVER_REDIRECT_PC_URL : NAVER_REDIRECT_PC_URL = "http://mysite.com/oauth/naver/callback.asp"
Dim NAVER_REDIRECT_MOB_URL : NAVER_REDIRECT_MOB_URL = "http://m.mysite.com/naverLogin/callback.asp"
Dim NAVER_OAUTH_AUTHORIZE_URL : NAVER_OAUTH_AUTHORIZE_URL = "https://nid.naver.com/oauth2.0/authorize"
Dim NAVER_OAUTH_TOKEN_URL : NAVER_OAUTH_TOKEN_URL = "https://nid.naver.com/oauth2.0/token"
Dim NAVER_GET_USER_INFO_URL : NAVER_GET_USER_INFO_URL = "https://openapi.naver.com/v1/nid/me"


Dim clsOAuth : Set clsOAuth = new clsNaverOAuth

Session("NAVER_STATE") = clsOAuth.generate_state
clsOAuth.clientId = NAVER_CLIENT_ID
clsOAuth.state = Session("NAVER_STATE")
clsOAuth.redirectUrl = NAVER_REDIRECT_PC_URL
Dim queryString : queryString = clsOAuth.authQueryString

Response.redirect NAVER_OAUTH_AUTHORIZE_URL & "?" & queryString


%>

인클루드 파일 설명
첫번째 소스 내용을 /Class/NaverOAuth.asp 위치에 저장한 것을 불러오는 부분

 

callback.asp
<%@Language="VbScript"%>
<!--#include virtual="/Class/NaverOAuth.asp"-->

<%
Dim NAVER_CLIENT_ID : NAVER_CLIENT_ID = "네이버클라이언트ID"
Dim NAVER_SECRET_KEY : NAVER_SECRET_KEY = "네이버비밀키"
Dim NAVER_REDIRECT_PC_URL : NAVER_REDIRECT_PC_URL = "http://mysite.com/oauth/naver/callback.asp"
Dim NAVER_REDIRECT_MOB_URL : NAVER_REDIRECT_MOB_URL = "http://m.mysite.com/naverLogin/callback.asp"
Dim NAVER_OAUTH_AUTHORIZE_URL : NAVER_OAUTH_AUTHORIZE_URL = "https://nid.naver.com/oauth2.0/authorize"
Dim NAVER_OAUTH_TOKEN_URL : NAVER_OAUTH_TOKEN_URL = "https://nid.naver.com/oauth2.0/token"
Dim NAVER_GET_USER_INFO_URL : NAVER_GET_USER_INFO_URL = "https://openapi.naver.com/v1/nid/me"

Dim clsOAuth : Set clsOAuth = New clsNaverOAuth

Dim state : state = clsCom.CheckisTrim(Request.QueryString("state"))
Dim code : code = clsCom.CheckisTrim(Request.QueryString("code"))
Dim Error : Error = clsCom.CheckisTrim(Request.QueryString("error"))
Dim error_description : error_description = clsCom.CheckisTrim(Request.QueryString("error_description"))

If error <> "" Then
response.write("error")
response.write("<br>")
response.write(error)
response.write("<br>")
response.write(error_description)
response.end
End If

If Session("NAVER_STATE") <> state Then
response.write("인증 실패")
response.write("<br>")
response.write(Session("NAVER_STATE"))
response.write("<br>")
response.write(state)
response.write("<br>")
response.end
End If

'''===전송할 파라미터 지정
clsOAuth.clientId = NAVER_CLIENT_ID
clsOAuth.state = state
clsOAuth.clientSecret = NAVER_SECRET_KEY
clsOAuth.code = code
'Response.write( clsOAuth.tokenAuthQueryString & vbNewline)


Dim respInfo
Dim profileInfo
Dim authToken

'토큰 발급 요청
Set respInfo = clsOAuth.httpRequest(NAVER_OAUTH_TOKEN_URL &"?"& clsOAuth.tokenAuthQueryString,"")

If respInfo.Exists("error")=true Then
response.write("토큰 접속 요청 에러" & "<br>" )
response.write(respInfo.Item("error") & "<br>" )
Else
Session("NAVER_ACCESS_TOKEN") = respInfo.Item("access_token")
Session("NAVER_REFRESH_TOKEN") = respInfo.Item("refresh_token")
response.write(Session("NAVER_ACCESS_TOKEN") & "<br>" )
response.write(Session("NAVER_REFRESH_TOKEN") & "<br>" )
'프로필 정보 조회
authToken = respInfo.Item("token_type") &" "& respInfo.Item("access_token")
Set profileInfo = clsOAuth.httpRequest(NAVER_GET_USER_INFO_URL, authToken)

If profileInfo.Item("resultcode") = 00 Then
Dim key : for each key in profileInfo.Item("response").enumerate()
response.write(key & " : " & profileInfo.Item("response").get(key) & "<br>" )
next
Else
response.write("프로필 조회 요청 에러" & "<br>" )
response.write(profileInfo.Item("resultcode") & "<br>" )
response.write(profileInfo.Item("message") & "<br>" )
End If
End If



'Session 등록이 클래스 안에서 안됨.
'objXMLHTTP.Send 파라미터로 요청 하려고 했으나, 요청이 잘못 됐다는 에러메시지가 계속 나옴.
%>

 

ps. 네이버로그인을 적용하면서 알 게 된 건데, 해당 기능은 OAUTH 2.0 기능을 사용하고
이 프로토콜은 IETF 표준으로 네이버만 사용하는 기술이 아닌 것이다.
페이스북, 트위터, 구글등 OAUTH 2.0 기능으로 로그인 기능을 제공 하고 있다.

ps2. 개발하면서 이상하다고 생각한게 토큰 갱신,삭제 부분이다. 몇몇 샘플 코드를 봐도
토큰 요청만 개발 해 놓고, 갱신, 삭제 부분은 만들어 놓지도 않았다.

이론적으로는 토큰 요청후  일정시간(expires_in )이 지나면 기존의 토큰은 사라지고 토큰 갱신을 해야 한다는 건데, 그렇게 하지 않아도 토큰 요청을 하면 새로운 토큰을 넘겨준다. 그러면 토큰 갱신이 별 의미가 없어 보인다.

또 토큰 삭제 역시 매뉴얼에는 어플리케이션 연동을 해제 할 때라고 나와 있지만 정작 네이버설정의 '외부 사이트 연결관리' 부분에는 연동한 사이트가 그대로 남아있다.

그에 대한 해답은 여기에서 찾았다.

결론은 엑세스 토큰이 문제가 생겼거나, 보안 이슈를 최소화 하기 위해서 인것 같다.

2016년 8월 24일 수요일

크롬 느려지는 이유.

크롬이 갑자기 어마어마하게 느려졌다.

원인은 역시나 인터넷 뱅킹.

그 중에서 '우리은행 보안로그 수집기'란 녀석

삭제하니 잘 된다. 완전 극혐

2016년 8월 5일 금요일

summit 스위치 초기화 방법

퍼온 내용. 출처 : http://lovevirus133.tistory.com/2

---------------------------------------------------------------

summit스위치를 비밀번호 분실 하여 초기화 하는 과정에서 자료를 찾아 보고 테스트 해보았다.

먼저 스위치에 콘솔로 연결 한뒤 전원플로그를 뺀다. 콘솔에서 스페이스바를 누른 상태에서 전원플로그를 다시 삽입한다.
여기서 bootrom → 이란 프롬프트가 나타날때 까지 스페이스바를 누르고 있어야 한다. bootrom →이란 프롬프트가 나타나면 h(help)를 누르면
아래와 같은 메뉴가 나타난다.


수행절차는 아래와 같다.
1. 1(primary code)을 선택한다. 그 후에 k(Erase selecte configuration)선택하여 선택된 configuration을 지운다.
2. 2(secondary code)을 선택한다 그 후에 k(Erase selecte configuration)선택하여 선택된 configuration을 지운다.
3. d(Force default configuration)을 선택한다. 그 후에 f(on board flash)를 선택하여 부팅한다.
이 절차를 마치면 패스워드를 더이상 입력 하지 않아도 된다. 스위치가 리셋 된 후에 login 프롬프트가 나타나면 admin이라고 치고, password 프롬프트가 나타나면
enter 키를 두번 치면 된다. 그럼 admin수준의 권한을 갖게 되고 다시 login과 password를 변경한 후에 저장하면 된다.

---------------------------------------------------------------

위와 같은 방법으로 admin 계정으로 로그인까지는 완료 하였으나, 패스워드 변경 후 save가 안된다. 아래의 에러 발생.
Command not supported in limited mode

네전따 카페에서 찾은 내용.

Ware 장비에서 Limit-mode에 빠지시면 아래 순서대로 해보세요.
1. #clear log static
2. #clear log diag
- These two commands will clear the error entries in the diag and static logs due to which switch is booting in limited mode.
- Now reboot the switch.
- Then to check the reason for the switch going into limited mode, run following command:
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><?xml:namespace prefix = o />
3. #run diag extended
===========================================
4. _enableBusStatsCLI
5. sh log messages hidden-buffer
[출처] summit48si limited 모드에서 빠져나오질 않네요 (네트워크 전문가 따라잡기) |작성자 렝렝

2번까지만 실행하고 리부팅 하니까 정상적으로 저장 됐다.

2016년 7월 29일 금요일

네이버페이 자바스크립트로 비활성화

네이버 페이를 연동시에 상품이 품절 인 경우는 비활성화를 해주어야 한다.


문제는 한개의 페이지가 아니라 옵션을 선택시 품절 여부를 보여 줄 경우 스크립트로 수정하는 방법을 모른다는 것. 네이버에 물어봐도 제대로 답변해 주지 않는다. 그냥 숨김 처리하라고 하는 데, 버튼이 있던 자리가 없어지는 건 아무래도 이상하다.


소스를 보니 가능 할 것 같아서 해 봤더니, 되긴 된다.


<div id="naverPayBtn"></div>
<script type="text/javascript" src="http://test-pay.naver.com/customer/js/naverPayButton.js" charset="UTF-8"></script>
<script type="text/javascript" >
//<![CDATA[
var npBtnOption ={
BUTTON_KEY: "naverPayBtnCertiKey", // 네이버페이에서 제공받은 버튼 인증 키 입력
TYPE: "A", // 버튼 모음 종류 설정
COLOR: 1, // 버튼 모음의 색 설정
COUNT: 2, //버튼 개수 설정. 구매하기 버튼만 있으면(장바구니 페이지) 1, 찜하기 버튼도 있으면(상품 상세 페이지) 2를 입력.
ENABLE: "Y", // 품절 등의 이유로 버튼 모음을 비활성화할 때에는 "N" 입력
EMBED_ID : "naverPayBtn",
BUY_BUTTON_HANDLER: buy_nc, // 구매하기 버튼 이벤트 Handler 함수 등록, 품절인 경우 not_buy_nc 함수 사용
//BUY_BUTTON_LINK_URL: "", // 링크 주소 (필요한 경우만 사용)
WISHLIST_BUTTON_HANDLER: wishlist_nc, // 찜하기 버튼 이벤트 Handler 함수 등록
//WISHLIST_BUTTON_LINK_URL: "", // 찜하기 팝업 링크 주소
"":""
}
naver.NaverPayButton.apply(npBtnOption);


//버튼기능(네이버페이 구매하기)
function buy_nc() {
...
return false;
}
function wishlist_nc() {
// 네이버페이로 찜 정보를 등록하는 가맹점 페이지 팝업 창 생성.
// 해당 페이지에서 찜 정보 등록 후 네이버페이 찜 페이지로 이동.
...
return false;
}
function not_buy_nc() {
alert("죄송합니다. 네이버페이로 구매가 불가한 상품입니다.");
return false;
}

</script>

 


아래의 코드로  ENABLE 상태를 변경.


	naverPayStatusChange: function(enable,option,btnHandler) {
$("#"+option.EMBED_ID).text("");
option.ENABLE = enable;
option.BUY_BUTTON_HANDLER = btnHandler;
naver.NaverPayButton.apply(npBtnOption);
}


ex) naverPayStatusChange("N",npBtnOption,not_buy_nc);

ps. 사용자가 네이버페이로 결제시 결제 완료, 실패 리턴이 없음. 그냥 보내면 끝이므로 주의

2016년 7월 18일 월요일

[asp] 스트링 변수에서 xml 가져오기

xml 형식은 다음과 같다.
<COLOR COLORCD="79" CODE="09" CODENAME="09 클래식블랙"/><COLOR COLORCD="9366" CODE="92" CODENAME="92 차콜+네이비옥스포드"/><COLOR COLORCD="9367" CODE="93" CODENAME="93 블랙+차콜하운드투스"/>

변수에서 가져오는 방법은 여기에서 확인 하였다.

위와 같이 해서 확인 하면 에러 발생.

XML 문서에서는 최상위 요소 하나만 허용됩니다.

변수 앞뒤로 <root>, </root> 를 붙여서 사용.

 

최종 코드
dim nodeCount, XMLDom,NodeList,theNode,Node, tmp
Set XMLDom = CreateObject("MSXML2.DomDocument.6.0")
XMLDom.async = false
tmp = "<root>"+rs("COLOR_XML")+"</root>"
XMLDom.LoadXML ( tmp )

theNode = "//COLOR"

Set NodeList = XMLDom.SelectNodes(theNode)
nodeCount = XMLDom.SelectNodes(theNode).length

if XMLDom.parseerror = 0 then
Response.Write(nodeCount)
For Each Node in NodeList
response.write(Node.GetAttribute("CODENAME") & "<br>")
Next
else
response.Write("Error Parsing Results")
end if
Set XMLDom = Nothing

2016년 7월 15일 금요일

dns_txt.c:(.text+0x35): undefined reference to `__res_query'

qmail 설치시 에러 발생

gcc -DBIND_8_COMPAT -O2 -o dktest dktest.o -L. -ldomainkeys -lcrypto `cat dns.lib`
./libdomainkeys.a(dns_txt.o): In function `dns_text':
dns_txt.c:(.text+0x35): undefined reference to `__res_query'
dns_txt.c:(.text+0xcf): undefined reference to `__dn_expand'
dns_txt.c:(.text+0x147): undefined reference to `__dn_expand'
collect2: ld returned 1 exit status
해결
yum install bind-libs

2016년 7월 13일 수요일

determining if ip address is already in use for device eth0 centos

determining if ip address is already in use for device eth0

위와 같은 오류가 발생.

아무리 찾아 봐도 원인을 알 수 없다.

ARPCHECK=no 옵션을 주면 에러가 안 난다고 하는데, 왠지 찝찝하다.

해당 옵션이 무엇인지에 대한 설명은 /usr/share/doc/initscripts-9.03.40/sysconfig.txt 에 나와 있다.
    ARPCHECKn=yes|no
If set to 'no', ifup will not try to determine, if requested ip address
is used by other machine in network.
Defaults to 'yes'.

네트워크에 있는 다른 머신에 의해 결정한다는 건데, 이름에서 추측하건데 arp 체크를 통해 서 중복되는 ip를 찾는 것 같다.

근데!!! 중복되는 IP 가 없어~!!!!

arping 을 해 보라는 둥.. tcpdump 를 잡아 보라는 둥.. 전부 해봐도 특별한 이유가 없다..

xenserver로 설치 한 거라서 조금 특별한 원인이 있지 않을 까도 싶다.

결국 그냥 사용하는 걸로..;;

 

참조:https://blog.cles.jp/item/6718




160928 추가.

ip 셋팅이 되어 있는 부분을 command로 다시 설정하면서 꼬이는 것 같다.
ifconfig eth0 down
service network restart

오류가 나는 인터페이스를 다운 시킨 후 네트워크를 재시작하면 없어진다.

원격에서 작업시 매우 주의!!

2016년 7월 4일 월요일

라이선스를 제공할 원격 데스크톱 라이선스 서버가 없으므로 원격 세션 연결 이 끊어졌습니다.

"라이선스를 제공할 원격 데스크톱 라이선스 서버가 없으므로 원격 세션 연결이 끊어졌습니다." 라는 에러 메시지가 나오면서 원격접속이 안된다.

라이선스 서버를 설치하고 그룹정책에서 적용을 해야 되는 데, 적용을 안 해 놔서 생기는 문제였다.

  1. mstsc /admin 명령으로 관리 세션은 연결이 가능 하다.

  2. 아래 사이트에서 자세히 설명해 놓음.
    http://tempdb.tistory.com/105
    http://taesany.tistory.com/105

  3. 원격에서는 regedit 권한 수정이 안된다.http://taesany.tistory.com/105 블로그에서 psexec 툴로 하면 가능 한것 같음. 해보지 않음

2016년 6월 24일 금요일

centos7 netstat

netstat 명령어가 기본적으로 사라지고, ss 명령어가 생겼다.

 

listening sockets  보기.
# ss -l

 

모든 소켓 보기.
# ss - a

 

TCP 소켓 보기.
# ss - t

 

UDP 소켓 보기.
# ss - u

 

소켓 사용하는 프로세스 보기.
# ss - p

 

소켓 사용하는 메모리 보기.
# ss - m

 

 

참조

No default or ui configuration directive found

centos 7 iso 파일로 설치 중 오류.

No default or ui configuration directive found

파일 잘못 받아서 생기는 문제.

iso 파일을 로컬에 받지 않고, 네트워크 드라이브로 연결된 폴더에 넣었더니, 문제가 발생한 것 같음.

다른 파일로 다시 받았더니, 파일 크기 자체가 다름.

2016년 5월 27일 금요일

AppLocker 사용법

administrators 를 제외하고 다른 일반 사용자에 대해서는 프로그램 실행 제한을 하려고 알아보다, AppLocker 란걸로 가능하단 걸 알게 됐다.

원하는 대로 잘 되지 않아 찾아 보니 기본적으로 아래와 같았다.

  1. 규칙이 없으면 해당 파일 형식의 모든 파일을 실행할 수 있다.

  2. 특정 규칙 컬렉션에 대한 AppLocker 규칙이 만들어져 있으면 규칙에서 명시적으로 허용된 파일만 실행할 수 있습니다.


그래서 규칙을 만들 때, 반드시 administrators 는 모든 파일을 사용가능 하게끔 같이 넣어줘야 한다. 그렇지 않으면 정책자체를 수정 할 수 없게 된다.

실행파일규칙에서 우클릭을 하면, 기본규칙 만들기를 클릭하면
Administrators 모든파일, Everyone Windows 폴더 모든파일, Everyone Program Files 폴더 모든 파일'이 생성 된다.

다른 규칙은 문제가 안되는 데, Everyone Windows 폴더 모든파일 규칙을 삭제 하면 원격 접속이 원할하게 되지 않는 다. 아마 다른 문제도 발생 할 것으로 보인다.

실행은 아래와 같다.

1. [시작] → [실행] → gpedit.msc 입력하고 엔터칩니다. 로컬 그룹 정책 편집기가 실행됩니다.
2. [컴퓨터 구성] - [Windows 설정] - [보안 설정] - [응용 프로그램 제어 정책] - [AppLocker]에서 설정하시면 됩니다.

 

최종 적용 설정 캡쳐

20160526154613

 

 

 

 

참조 : AppLocker 규칙 동작 이해

2016년 5월 26일 목요일

윈도우 방화벽 해외 IP 차단.

윈도우 방화벽을 이용해서 한국에서의 접속 IP 만 접근 가능 하도록 파워쉘로 만들었다.


특정 포트를 지정해 줘야 한다. 기존에 allow되어 있던 부분은 사용안함 처리 해야 한다.


 


소스는 아래와 같다.


#get-help about_signing 참조하라는 에러 발생시,
#Set-ExecutionPolicy RemoteSigned  실행.


#############Config#################
$countryCode="KR" #차단을 하지 않을 나라의 CountryCode
$geoIPcsvPath="c:\GeoIPCountryWhoisPaid.csv"
#$geoIPcsvPath="\GeoIPCountryWhois.csv" #ISE에서 실행시 찾지 못함.
$ruleName="allowCountry"
$allowPort="3389,1433"
#############Config#################


$geoData=Import-Csv $geoIPcsvPath -header sIP, eIP, cc |  where-object {$_.cc –eq $countryCode} 
$geoDataTotal=$geoData.Count
$remoteIP=""


######  룰이 있는 지 체크 ########
function ruleExistsChk ($ruleName)
{
    $fw=New-object -comObject HNetCfg.FwPolicy2; # http://blogs.technet.com/b/jamesone/archive/2009/02/18/how-to-manage-the-windows-firewall-settings-with-powershell.aspx 
    $RuleCHK=$fw.rules | where-object {$_.name –eq $ruleName}
    if(!$RuleCHK){
    #$deny_rule_name + " 룰이 생성되어 있지 않습니다."; exit; 
    #허용하는 룰 생성.
    netsh advfirewall firewall add rule name="$ruleName" localport="$allowPort" protocol=TCP localip=any dir=in action=allow profile="any" interfacetype="any"
    }
}
######  룰이 있는 지 체크 ########


$count=1
foreach ($geoIP in $geoData)
{
    #$remoteIP+=@($geoIP.sIP+"-"+$geoIP.eIP+",") #배열로 저장.
     $remoteIP+=$geoIP.sIP+"-"+$geoIP.eIP+","
     try {

        
         #remoteAddr가 한개의 룰에 약 300개 이상이면 등록이 안됨. 안전하게 200으로 설정.
        if(($count%200) -eq 0)
        {
            $makeRuleName=$ruleName+$countryCode+$count
            ruleExistsChk($makeRuleName)
            netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP"
            $remoteIP=""
        }elseif($geoDataTotal -eq $count){
            $makeRuleName=$ruleName+$countryCode+$count
            ruleExistsChk($makeRuleName)
            netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP"
            $remoteIP=""
        }

    }catch {
      Write-Warning "Error occured: $_"
    }
     $count++

}


GeoIPCountryWhois.csv을 이용한 나라별 윈도우 방화벽 차단 등록.

나라별방화벽차단등록

www.2cpu.co.kr 에서 제작된 중국쪽 ip대역 차단 스크립트를 보게되었다.

실제로 GeoIPCountryWhois.csv 파일에 있는 걸 스크립트로 만든 거라서

GeoIPCountryWhois 파일이 업데이트 되면 다시 수정 해야 하는 번거로움이 있어서

파워쉘 스크립트로 만들었다.

처음에는 vb 로 만들려고 했으나, vb 자체의 자료도 별로 없고, 기존 프로그래밍 언어와 다른 점이 너무 많아서 powershell 로 바꿨다.

요즈음의 왠만한 윈도우 서버는 powershell 을 지원하니 왠만해서는 될 듯하다. 테스트는 안 해봤다.

최신의 GeoIPCountryWhois.csv 파일은 여기서 다운 받을 수 있다.

근데 파일 자체가 최신이 아니다. 2년전 자료이다.

진짜 최신자료는 www.maxmind.com 에서 유료로 받을 수 있다.



소스
#문의는 http://blog.netchk.net/
#############Config#################
$countryCode="CN" #차단할 나라의 CountryCode
#$geoIPcvsPath="c:\GeoIPCountryWhois.csv"
$geoIPcvsPath="\GeoIPCountryWhois.csv"
$ruleName="blockCountry"
#############Config#################


$geoData=Import-Csv $geoIPcvsPath -header sIP, eIP, start, end, cc, cn |  where-object {$_.cc –eq $countryCode} 
$geoDataTotal=$geoData.Count
$remoteIP=""


######  룰이 있는 지 체크 ########
function ruleExistsChk ($ruleName)
{
    $fw=New-object -comObject HNetCfg.FwPolicy2; # http://blogs.technet.com/b/jamesone/archive/2009/02/18/how-to-manage-the-windows-firewall-settings-with-powershell.aspx 
    $RuleCHK=$fw.rules | where-object {$_.name –eq $ruleName}
    if(!$RuleCHK){
    #$deny_rule_name + " 룰이 생성되어 있지 않습니다."; exit; 
    netsh advfirewall firewall add rule name="$ruleName" localip=any dir=in action=block profile="any" interfacetype="any"
    }
}
######  룰이 있는 지 체크 ########


$count=1
foreach ($geoIP in $geoData)
{
    #$remoteIP+=@($geoIP.sIP+"-"+$geoIP.eIP+",") #배열로 저장.
     $remoteIP+=$geoIP.sIP+"-"+$geoIP.eIP+","
     
     #remoteAddr가 한개의 룰에 약 300개 이상이면 등록이 안됨. 안전하게 200으로 설정.
    if(($count%200) -eq 0)
    {
        $makeRuleName=$ruleName+$countryCode+$count
        ruleExistsChk($makeRuleName)
        netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP"
        $remoteIP=""
    }elseif($geoDataTotal -eq $count){
        $makeRuleName=$ruleName+$countryCode+$count
        ruleExistsChk($makeRuleName)
        netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP"
        $remoteIP=""
    }

     $count++

}

예전 차단하는 스크립트에서도 썼지만 remoteAddress 에 limit 이 걸려 있다.

단일 IP는 약 1000개 인데, IP range는 약 300개 정도이다.

그래서 200개 단위로 rule을 다시 생성한다.



ps. 위의 소스를 이용해서 한국만 허용하고 해외는 모두 차단 하는 스크립트를 만들었는 데, 안된다. 리눅스의 iptable 같은 경우 순서에 따라 적용이 되기 때문에 모든 IP 차단, 한국 IP 허용 으로 하면 된다.

윈도우 방화벽은 순서에 따라 적용되지 않는다. 한국 IP 허용, 모든 IP 차단 해도 안되고, 순서를 바꿔서 등록 해도 역시 안된다.

방법은 있는데, 기존에 등록되어 있는 허용 포트 부분을 모두 지정하는 것이다. 한국 IP 만 등록해 놓은 룰을 적용한 후, local port 를 설정하고, 기존에 적용되어 있던 부분을 삭제 하면 된다.

문제는 포트별로 다른 IP 차단이 안된다는 점. 해외 IP를 전부 등록해야...;;

ps2. 방화벽 규칙에서 여러 룰에서 차단과 허용이 둘다 있으면 차단 시킨다.

https://technet.microsoft.com/ko-kr/library/cc755191(v=ws.10).aspx

2016년 5월 21일 토요일

Talend Open Studio(TOS) 암호화, 복호화.

TOS를 사용해서 DB 데이터를 contexts로 저장 하였다. contexts로 exprot 하면 해당 내용들이 파일로 저장되기 때문에, 몇몇개의 값 때문에 다시 빌드 하지 않아도 된다.

일종의 설정파일이다.

문제는 type을 password로 지정하면 암호화가 되는 데, 파일의 내용을 수정할 수가 없다.

이렇게 되면 패스워드 때문에 다시 빌드를 실행해야 되기 때문에 contexts로 만든 의미가 없어진다.

물론 String으로 바꿔서 저장하면 되지만 clear text로 저장되는 건 조금 꺼림칙하다.

db 접속을 위해서는 복호화가 가능 해야 하지 않을 까 생각했더니, 역시나 복호화가 가능하다.

TOS 소스 자체는 오픈되어 있고, github에서 볼 수 있다.

PasswordEncryptUtil.java 부분에 encryptPassword, decryptPassword가 있는데,

이 부분을 가져다 사용해서 간단한 프로그램으로 만들어 놓으면, 다시 빌드해야 하는 번거로움은 덜 수 있다.

2016년 5월 11일 수요일

qmailanalog 설치 및 사용 시 에러

qmailanalog를 설치 하려고 다운 받았다.

make 했더니 오류가 난다.
/usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches non-TLS reference in strerr.a(strerr_sys.o)
/lib/libc.so.6: could not read symbols: Bad value
collect2: ld returned 1 exit status

위와같은 오류발생시 error.h파일에 extern int errno; 이줄 삭제 #include <errno.h> 그위치에 이줄 추가한다.
출처
cat /var/log/maillog | awk '{$1="";$2="";$3="";$4="";$5="";print}' > /tmp/qmailLogTmp
cat /tmp/qmailLogTmp | /usr/local/qmailanalog/bin/matchup | /usr/local/qmailanalog/bin/zoverall > /tmp/qmailLog

위와 같이 했더니, 오류 발생.
matchup: fatal: unable to write fd 5: file descriptor not open

나눠져 있는 로그 파일을 합치라고 하면서 아래와 같이 코드를 적어 놨음.
(무려 중국 블로그)
<log.1 matchup >out.1 5>pending.2
cat pending.2 log.2 | matchup >out.2 5>pending.3
cat pending.3 log.3 | matchup >out.3 5>pending.4

왜 이렇게 하는 지 모르겠음.

그냥 이렇게 하니까 된다.
cat /var/log/maillog* | awk '{$1="";$2="";$3="";$4="";$5="";print}' > /tmp/qmailLogTmp
cat /tmp/qmailLogTmp | /usr/local/qmailanalog/bin/matchup | /usr/local/qmailanalog/bin/zoverall > /tmp/qmailLog

/tmp/qmailLog 내용을 보면

[root@mail qmailanalog-0.70]# cat /tmp/qmailLog
Basic statistics

qtime is the time spent by a message in the queue.

ddelay is the latency for a successful delivery to one recipient---the
end of successful delivery, minus the time when the message was queued.

xdelay is the latency for a delivery attempt---the time when the attempt
finished, minus the time when it started. The average concurrency is the
total xdelay for all deliveries divided by the time span; this is a good
measure of how busy the mailer is.

Completed messages: 18684
Recipients for completed messages: 24230
Total delivery attempts for completed messages: 24458
Average delivery attempts per completed message: 1.30903
Bytes in completed messages: 5.20127e+09
Bytes weighted by success: 1.00912e+10
Average message qtime (s): 15.4838

Total delivery attempts: 24458
success: 24060
failure: 170
deferral: 228
Total ddelay (s): 158313.276733
Average ddelay per success (s): 6.579937
Total xdelay (s): 169514.560113
Average xdelay per delivery attempt (s): 6.930843
Time span (days): 7.42548
Average concurrency: 0.264222

잘 나온다.

근데 내가 원하는 내용이 아니다. ㅠㅠ

2016년 5월 10일 화요일

bulk insert 시 에러.

아래와 같은 에러 메시지 발생
메시지 4866, 수준 16, 상태 8, 줄 1
대량 로드하지 못했습니다. 데이터 파일의 행 1, 열 24에서 열이 너무 깁니다. 필드 종결자와 행 종결자를 제대로 지정했는지 확인하십시오.
메시지 7301, 수준 16, 상태 2, 줄 1
연결된 서버 "(null)"의 OLE DB 공급자 "BULK"에서 필수 인터페이스("IID_IColumnsInfo")를 가져올 수 없습니다.

필드 종결자를 바꿈.
\r\n 이 아님.
\n 으로 바꾸고 잘됨.

mssql 우편번호 쉽게 넣기, 업데이트

관리하는 사이트 중에 우편번호를 DB 에 저장해서 사용하는 곳이 있다.
DB에 저장해서 사용하다 보니 주기적으로 계속 업데이트를 해 줘야 한다.
sql server management studio 프로그램의 데이터 가져오기를 이용해서 넣어 줬다.

우체국 사이트에서 제공하는 데이터가 각 도별 txt 파일이다.
우리나라의 전체 도가 17개인데, ssms 프로그램으로 넣으려면 무려 반복 노가다를 17번을 해야 한다.

bulk insert를 이용해서 한번에 insert 시키도록 하였다.
bulk insert를 하려면 양식(formatfile)이 필요하다.
cmd 창을 열고 아래와 같이 입력해서 뽑아 내자.
C:\Users\Administrator>bcp mydb.dbo.T_ZIPCODE format nul -c -x -f crmZipcode.a.xml -t"|" -T

해당 파일을 바로 사용 하면 좋은데, 우체국 제공 컬럼과 실제 컬럼이 일치 하지 않는 다. 수정이 필요하다.
관리 사이트와 우체국 우편번호 데이터 컬럼의 다른 점은 다음과 같다.
1. 20번 컬럼인 '행정동' 컬럼이 없다.
2. 25번 컬럼인 '구우편번호' 컬럼이 없다.
3. 26번 컬럼인 '우편번호일련번호' 컬럼이 1번째에 있다.

변경하면 다음과 같다.
<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<!--파일의 필드 -->
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="14" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="3" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="60" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="4" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="60" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="5" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="60" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="6" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="7" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="100" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="8" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="100" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="9" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="160" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="10" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="500" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="11" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="4" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="12" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="13" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="14" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="50" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="15" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="400" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="16" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="500" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="17" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="60" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="18" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="19" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="20" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="100" COLLATION="Korean_Wansung_CI_AS"/> <!-- 행정동 -->
<FIELD ID="21" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="100" COLLATION="Korean_Wansung_CI_AS"/> <!--산여부 -->
<FIELD ID="22" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="4" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="23" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="24" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="25" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="26" xsi:type="CharTerm" TERMINATOR="\n" MAX_LENGTH="12"/>
</RECORD>
<!--서버의 필드 -->
<ROW>
<COLUMN SOURCE="26" NAME="SEQ" xsi:type="SQLINT"/>
<COLUMN SOURCE="1" NAME="ZIPCODE" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="2" NAME="SIDO" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="3" NAME="ESIDO" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="4" NAME="SIGUNGU" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="5" NAME="ESIGUNGU" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="6" NAME="EUPMRN" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="7" NAME="EEUPMRN" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="8" NAME="ROADCODE" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="9" NAME="ROADNAME" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="10" NAME="EROADNAME" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="11" NAME="ZIYN" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="12" NAME="GUNBON" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="13" NAME="GUNBU" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="14" NAME="GUNSEQ" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="15" NAME="DABE" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="16" NAME="GUNNAME" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="17" NAME="BUBCODE" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="18" NAME="BUBDONG" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="19" NAME="RI" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="21" NAME="SANYN" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="22" NAME="ZIBON" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="23" NAME="EUPSEQ" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="24" NAME="ZIBU" xsi:type="SQLNVARCHAR"/>
</ROW>
</BCPFORMAT>
<!-- 서버의 필드에 없는 것은 컬럼을 넣지 않음. -->
<!-- 파일의 필드는 쓰던 쓰지 않던 모두 넣음 -->
<!-- 베이스가 되는 파일 생성 명령어 : C:\Users\Administrator>bcp mydb.dbo.T_ZIPCODE format nul -c -x -f crmZipcode.a.xml -t"|" -T -->

이 양식을 이해 하는 데, 조금 오래 걸렸다.
간단히 설명하면,
1. 상단 RECORD 는 파일의 컬럼이다. 전부 있어야 된다.
2. 하단 ROW는 테이블의 컬럼이다. 수정해서 써야 한다.
내껄 보면 26번이 처음 있고, 20번과 25번이 없는 걸 알 수 있다.
bulk insert 쿼리는 다음과 같다.
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\강원도.txt'            WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\경기도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\경상남도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\경상북도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\광주광역시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\대구광역시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\대전광역시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\부산광역시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\서울특별시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\세종특별자치시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\울산광역시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\인천광역시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\전라남도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\전라북도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\제주특별자치도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\충청남도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\충청북도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )


FROM 절과 formatfile 의 위치를 수정해서 사용하면 된다.
path를 변수로 만들고 싶었으나, 기본적으로 지원하지 않고, 동적 sql을 사용해야 한다길래 그냥 뒀다.

 

대략 30분가량의 노가다를 없앴다.  :)

2016년 5월 4일 수요일

MSSQL bak 파일을 이용하여 복원

백업된 bak 파일을 복원
1. 복구할 DB 선택, 우클릭 속성 , 옵션 -> 엑세스 제한을 RESTRICTED_USER 로 변경.

(
RESTRICTED_USER
RESTRICTED_USER를 사용하면 db_owner 고정 데이터베이스 역할과 dbcreator 및 sysadmin 고정 서버 역할의 멤버만 데이터베이스에 연결할 수 있습니다. 연결할 수 있는 멤버의 수에는 제한이 없습니다.데이터베이스에 대한 모든 연결은 ALTER DATABASE 문의 termination 절에 지정된 시간대에 끊어집니다.데이터베이스가 RESTRICTED_USER 상태로 바뀐 후 자격이 없는 사용자의 연결 시도는 거부됩니다.
)


2. 복구할 DB 선택, 태스크 -> 복원 -> 파일 및 파일 그룹 선택
3. 복원에 사용할 원본을 장치 -> bak 파일 선택
5. 옵션에서 기존 데이터베이스 덮어쓰기 체크
6. 실행.
검색하다 보면 블로그에 mssql DB 복원 관련 글에서 엑세스 제한을 single user로 변경하고 복원하라는 글이 있는데,
이렇게 하면 기존 웹프로그램이나, 기타 DB 접속 프로그램이 먼저 선점하면 아주 골치 아픈 일이 발생한다.

2016년 4월 8일 금요일

Device eth0 does not seem to be present, delaying initialization 에러

서버 파워가 나갔다. 완전 같은 기종으로 유휴 장비가 있어서
하드디스크만 교체하여 올리니 바로 올라갔다.

네트워크가 안된다.
Device eth0 does not seem to be present, delaying initialization 에러 발생.

여기 참조해서 처리.

networking interface rules이란게 있는 것도 처음 알았다.

방법은 간단했다.
# rm /etc/udev/rules.d/70-persistent-net.rules
# reboot

이렇게 하면 해당 파일을 os가 다시 만든다.

그리고
/etc/sysconfig/network-scripts/ifcfg-eth0
파일에서

새로 생성된 rules 파일에 있는 HWADDR 로 바꾸고,
UUID 부분은 삭제한다.

그리고 service network restart.

네트워크가 올라간다.

2016년 3월 8일 화요일

LG HBS900 사용후기

3달간 사용후 느낀점

기존 HBS700를 사용했었음.

1. 고질적인 통화 불량 여전함. 주변 소리를 차단하는 기능이 없어서 상대방이 무척 시끄럽게 들린다고 함. 이게 제일 불만.
2. 음질적인 부분도 하마카돈가 제휴 했다고 하지만 별로 못 느낌.
3. 줄 자동으로 감는 부분은 좋음.
4. 충전은 출퇴근만 2시간 정도만 사용하는 거라, 부족하지 않았음. 배터리 확인시 '보통입니다.' 라고 확인 했을 때 4시간 정도 사용가능 했음.
5. HBS700 보다는 약간 뼈대(?)가 약간 더 뻣뻣한 느낌이 있음.

6. 왼쪽 스틱(?)을 아래쪽으로 계속 누르면 현재 배터리 상태를 알려주는 데, 음악 재생시에는 볼륨을 줄여버린다. 완전 끝까지 내리고 난 후 배터리 상태를 알려준다.

2016년 3월 4일 금요일

jqgrid onCellSelect 대체.

jqgrid 사용시 컬럼(셀) 선택 정보를 가져오고 싶어서 검색해 보니

onCellSelect 가 있음.

근데 왜인지 안됨.

onClick 으로 대체 사용.

2016년 2월 6일 토요일

진짜 맛없는 치킨

강정이 기가막혀’에서 두마리 치킨으로 세트로 시켰다.


만9천원이나 하는 가격에 일요일까지 버티려고 했다.


내 살다살다 치킨을 버리긴 처음이다.


치킨이 맛 없을 수도 있구나 라는 걸 처음 알았다.

2016년 1월 29일 금요일

네트워크위치 추가시 에러. 입력 한 폴더가 올바르지 않습니다

네트워크 위치 추가하려고, ftp://111.222.333.444 로 위치 추가 하려고 했더니,

입력 한 폴더 가 올바르지 않습니다. 라고 에러남.

이것저것 해보다 안되서 영문으로 구글 검색.

여기에서 찾음.

아래 코드를 .reg 확장자로 저장해서 실행니까 됐음. (안될수도...)
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\ftp]
@="URL:File Transfer Protocol"
"AppUserModelID"="Microsoft.InternetExplorer.Default"
"EditFlags"=dword:00000002
"FriendlyTypeName"="@C:\\Windows\\system32\\ieframe.dll,-905"
"ShellFolder"="{63da6ec0-2e98-11cf-8d82-444553540000}"
"Source Filter"="{E436EBB6-524F-11CE-9F53-0020AF0BA770}"
"URL Protocol"=""
[HKEY_CLASSES_ROOT\ftp\DefaultIcon]
@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,75,00,72,00,\
6c,00,2e,00,64,00,6c,00,6c,00,2c,00,30,00,00,00
[HKEY_CLASSES_ROOT\ftp\shell]
@="open"
[HKEY_CLASSES_ROOT\ftp\shell\open]

2016년 1월 28일 목요일

구글 카드보드 자석 원리

구글 카드보드 자석 원리

구글 카드보드를 구매 후 이것저것 해보다 문득 든 생각.

자석의 메뉴 클릭 원리

검색 해 봤지만 이거다 하는 내용이 없었다.

나무위키에서 스마트폰의 나침반을 이용한 거라고 나와 있다.

스마트폰의 센서의 종류에 대해서 찾아 보니, 지자기 센서가 있다.

지자기 센서를 이용해 나침반 어플을 만든다.

영어로는 Geo-magnetic Sensor

딱 감이 온다.

 

그래서 테스트 해 보았다.

스마트폰의 센서 테스트를 위해 무료 어플인 'Sensor Box for Android'를 사용했다.

스마트폰은 갤럭시 노트4 이다.

 

Screenshot_2016-01-28-10-08-10

기본 이미지

 

Screenshot_2016-01-28-10-08-21

자석을 폰의 아래 쪽에 위치. 약간의 변화가 있다.

 

 

Screenshot_2016-01-28-10-08-38

자석을 폰의 위 쪽에 위치. 매우 큰 변화.

 

결론.
- 구글 카드보드의 자석으로 메뉴 선택 하는 건, 지자기 센서를 통해 변화폭을 감지하여 구현한 것이다.
- 카드보드의 자석 위치를 폰의 위쪽에 두면 더 잘 인식된다. ( 다른 폰은 다를 수 있지만...)

 

2016년 1월 27일 수요일

윈도우 서버 접속 사용자, IP 확인.

윈도우 이벤트 로그를 통한 접속 사용자 확인 하는 파워쉘.

윈도우에서 제공하는 게 있음

logonactivity.ps1

출처

2016년 1월 19일 화요일

cisco arp timeout 변경

서버 아이피를 변경시 바로 적용 되지 않는 다.

이유는 스위치에 arp 테이블에서 서버의 맥주소와 ip 주소를 매핑해서 가지고 있는 ARP 테이블이 있기 때문이다.

cisco 의 arp 테이블 관련 내용은 아래와 같다.

 
#seconds 부분은 Input 값
#arp 캐시를 가지고 있는 시간.변경
arp timeout seconds

#삭제
no arp timeout seconds

#직접 캐시 삭제
clear arp-cache

기본 값은 14400 초(4시간)

 

스위치에서 확인.
Reno_Backbone#sh interfaces 
Vlan1 is down, line protocol is down
Hardware is Ethernet SVI, address is 001b.d5b6.27bf (bia 001b.d5b6.27bf)
MTU 1500 bytes, BW 1000000 Kbit, DLY 10 usec,
reliability 255/255, txload 1/255, rxload 1/255
Encapsulation ARPA, loopback not set
ARP type: ARPA, ARP Timeout 04:00:00
...

 

출처