RoadMap

Programming 2021. 11. 11. 16:29 Posted by ­행복

https://roadmap.sh/roadmaps

개발자로서의 로드맵!

있어보이려는 공부보다는, 진짜 있기 위한 개념을 잡기 위한 공부

그리고 다시 그것이 레쥬메를 아름답게 장식할지어다..

솔직히 레쥬메들 보면 별거 없음. 실력들은 거기서 거기임!

다른점은 메일 메일 물주고 가꾸는 나무처럼 자꾸만 가꾸면

내적으로는 하다못해 지식 한 자라도 더 보게되고,

외적으로는 레쥬메가 더 아름다워지기도함.(최소한 영작을 여러번 하면서 자연스러운 문장이 됨)

 

Developer Roadmaps

Community driven roadmaps, articles, guides, quizzes, tips and resources for developers to learn from, identify their career paths, know what they don't know, find out the knowledge gaps, learn and improve.

roadmap.sh

 

 

 

 

https://landscape.cncf.io/

클라우드, MSA, 이제는 피할 수 없는 숙명!

그동안 잘못된 상식

. 데이터는 정리해야하는 것이야 -> 절대 정리 못함 방치하고 빨리 찾아서 활용하는게 능력!(찾은 데이터도 또 방치된다)

. 서버는 컴퓨터는 집에다 두고 쓰면 전기세 빼고는 공짜니까 편해! -> 절대 공짜가 아니다. 클라우드에 올려놓고 서비스료를 내면서 쓰는게 데이터를 분실할 위험부담뿐 아니라 그 데이터를 분석하고 제안해서 최적의 가치를 알려주는 일을 한다. 클라우드 사용법을 익히는게 곧 역량이 된다는 것은 덤이다. 예전에 컴퓨터 설치만 해도 전산실에 취업했던 시절을 떠올려보라. 클라우드가 그런것이다. '클라우드 활용 능력'이 모든 IT인의 역량을 말해준다. 따라서 클라우드를 잘 사용하는 것만으로 취업이 가능함. 제발 구독경제 시대에 돈 아끼지말고 서비스 이용료 내면서 개인서버 운영은 클라우드 쓰자.. 너 그러려고 돈버는거다.

. 컴퓨터는 활용능력보다는 개발능력이 중요해!! -> 절대 아니다. 내가 믿었던 툴도 하루아침에 다른 툴에 의해 퇴물이 되는 세상에 살고 있다. 개발자는 모름지기 더 나은 툴을 '발견'하고 '활용'해야 하는 숙명에 있다. 그것이 반복 숙달 되다보면 부가적으로 개발도 잘하게 될 것이므로 툴을 찾고 숙달/활용하는 시간을 아낌없이 투자하자!

. 한번 배운 지식은 까먹지 않게 복습/암기해야해! -> 아니다. 어차피 업계에서는 절대 선과 같았던 지식도 부서(보직) 변경하면 거들떠도 안보는 죽은 지식(내입장에서)이 되는 경우가 많다. 그 분야에 대해서는 현역이 예비역으로 되는 것이다. 하루 하루 먹고 살기도 힘든데 굳이 계속 현역처럼 잘 할 필요 없다. 다만 백신주사처럼 항체가 들어오면 면역 반응이 되게끔 '정리'를 무척 잘 해 두어야 한다. 그런 사람이어야만 성공적 이직이 가능하다. 어차피 목표는 '양질의 일자리' 내지는 '좋은 사람이 있는 조직'일뿐, 돈이나 부귀영화는 아니다. 얼마나 IT를 잘하려고 고달픈 삶을 선택할래? 그래봤자 너는 마크 저커버그처럼 될 수 없다. 좋아하는 IT를 하다 보면 길은 언제나 있을것이니, 하고싶은 분야를 '즐겁게' 하자.

이렇게 일기를 쓰는것과 로드맵을 정하는 것도 그 중 일부다. 최소한 계속 이쪽 일을 생각하면서 항상성을 유지하면서 뇌가 새로운 것을 받아들이는 것에 대해 거부감이 없는 상황인 것과 복습이 수월한 모드가 되는 것만으로도

 

CNCF Cloud Native Interactive Landscape

Filter and sort by GitHub stars, funding, commits, contributors, hq location, and tweets. Updated: 2021-11-11 05:54:29Z

landscape.cncf.io

큰 그림을 보자. 요즘은 각종 툴들과 개개인들이 만든 부품들이 서로 잘났다고 난무하는 시절이라 홍대 인디 음악 아티스트처럼 듣보잡 솔루션들이 마치 업계 홍대부심 부리는 사람들처럼 들어와 있다. 이 모든 것을 '들어는 봐야' 대화가 된다. 로드맵과 랜드스캐이프가 중요한 이유

'Programming' 카테고리의 다른 글

파이썬 undefined 처리방법  (0) 2020.08.06

gitkraken pro 사용 도전

Programming/Tools 2021. 11. 11. 15:58 Posted by ­행복

1. 졸업생이지만 대학교 메일을 사용할 수 있음. 모교에 감사합니다^^

2. 나의 git 계정에 내 학생 이메일을 추가하고 인증을 통해 등록함

3. git에서 student pack을 신청함

4. 학생증을 요구해서 10년전 학생증을 꺼내서 올림. 안된다하면 할수없지

확인 과정을 거친다는데 일단은 내고 나니 Pro가 생김

5. gitkraken을 설치함

6. gitkraken에서 github계정으로 로그인 해야 함 (google로 로그인하니 7-day trial이 뜸)

7. local repo를 불러와서 pull을 하니 intellij보다 속도가 훨씬 빠르다. 강력한 툴

 

파이썬 인코딩 개삽질기

Programming/카톡봇 2021. 5. 17. 19:55 Posted by ­행복

이건 안적어두면 진짜 인생 억울해서 적는다.
걸린시간 : 반나절이상(약6시간)
하려는것: 표를 메일 첨부 발송 자동화
데이터 추출은 csv로 한다.
csv만드는건 파이썬으로 한다.

csv를 엑셀로 열어서 너비 맞추고 테두리 칠해서
메일에 붙여넣으면 저절로 만들어진다.



근데
크롬으로 자동화한 브라우저는 엑셀 표 붙여넣기가 안된다. html5 방식이라 보안상 붙여넣기를 한번 더 html5상에서 선택하는 이미지 팝업이 뜨는데 그걸 자동화 툴이 선택 못한다. 미치겠다.

그래서 ie로 다시 다 만들었다. 힘들게 삽질 노가다 했다.
그런데 ie 로 사내 메일에 로그인시 사내 메신저도 떠 버린다. 이것도 힘들게 삽질 노가다 했다.


그런데 부서장님이 결과에 한글을 넣고 싶다고 하셨다.
파이썬에서 utf8로밖에 저장이 안된다.
그리고 빌어먹을 ms엑셀은 절대 utf8을 디폴트로 Csv를 여는 것이 없다. 빌어먹을

방법 연구
1. 파이썬을 ansi로 기록하기
-> 미친듯이 안되어서 포기. 안됭 이유는 계속 인코딩 오류나고 리눅스의 한글 문자를 파이썬이 못 읽어가서 encoding:949 encoding:euc-kr 다 안됨

2. 엑셀에서 외부 텍스트를 열 때 디폴트로 utf8로 열리게 하기
이거 아무리해봤는데 레지 옵션 65001 넣는거까지 구글에서 찾아서 해봤는데 안됨

3. 파일명 앞에 \Ufeff를 붙이면 된다는데
이것도 아무리해도안됨.
파일명앞에 붙이면 그냥 csv파일 앞의 데이터에 feff만 붙어있는것뿐이었음
f.write(u'feff')
뭐 별지랄을 해도 안됨

그러다가 마지막에 찾아서 성공한게 있음
import codecs
f.write(codecs.BOM_UTF8)
이거 해주면 ms excel에서도 한글이 잘 나옴

UTF8 with BOM
하나 배워간다
더 화가 나서 자세히는 못쓴다

'Programming > 카톡봇' 카테고리의 다른 글

카톡봇 입문  (0) 2019.09.20

파이썬 undefined 처리방법

Programming 2020. 8. 6. 18:48 Posted by ­행복

https://ondemand.tistory.com/m/258

Python 에서 선언되지 않은 변수를 처리하는 방법

언어마다 선언되지 않은 변수를 처리하는 방법들이 조금씩 다른 것 같습니다. 가령 Javascript 에서는 변수가 선언되지 않았을 때 undefined 인지를 확인하는 방법으로 선언되지 않은 변수를 조건문��

ondemand.tistory.com


처음 발단은
'공용'을 보유한 사용자들만 '전용'을 보유했는지 여부에 따라서 Flag라는 변수에다가 결과값을 저장하게끔 코딩을 했다.
'공용'을 보유하지 않은 사람의 경우를 if문으로 처리하기 위해 Flag가 선언되지 아니한 경우를 찾고 있었다.
'공용'을 보유하지 않은 사람들은 Flag라는 변수 자체가 선언되지 않았기 때문에 파이썬에서는 NameError를 출력할 수 밖에 없다.
Javascript는 undefined를 활용하면
if (Flag==undefined) 이런식으로 코딩했던 이력이 있기에 그런 아이디어로 코딩을 하고자 찾아보는 중이었다.

그래서 위에 첨부한 링크와 같은 내용을 구글링해서 찾아냈다. 어쨌든 파이썬은 변수를 선언 안하면 undefined라고 활용할수가 없는 언어임이 결론이었다. 그런데 내가 코딩한 다른 소스코드를 보다보니 이미 내가 그것을 처리했었다.
기존에 발급받은 auth키를 header에 넣고 request를 보내서 key값을 가져온다. 그다음에 key값을 가지고 사용자 검색을 가능하게 되는 API가 있다.
나는 여기서 처음에 Key값이 선언되지 않은 경우라면 최초 1번만 인증을 받고, Key값이 있으면 skip을 하고 싶었다. 근데 그게 결국 변수의 undefined 조치방법과 동일한 내용이다.

결론은 과거의 자신을 자랑하고싶은 뻘글..이다.
try:
변수
except NameError as e:
변수선언
finally:
코드 작성

여기서 except부분을 활용하면 undefined에대한 대처가 가능할듯. 근데 저렇게 할바옌 처음부터 변수='어떤값' 넣고 프로그램 실행시키면
변수를 선언하고 그 변수의 값인 '어떤값'이 그대로 안바뀐 경우, 변수가 한번도 선언되지 않은 undefined상태와 같은 효과일것같다. 조금만 아이디어를 내면 해결할 수 있다. 메모리효율성을 차치하고서라도..방법은 있다. 그래서 굳이 구글링해도 많이 안나오는 것인지도...

해당 아이디어에 영감을 준 소스코드는 아래 첨부한다.

def Init():
headers1 = {'auth':'abcda0' , 'auth-token':'0S2AbC'}
res = request.post(Url,headers=headers1)
global key
key = res.json()['authcode']
#json형태의 리턴값을 Json으로 만들어서 그중 authcode에 해당되는 값만 key변수로 취함



try :
key
except NameError as e:
print("처음 실행했음. 인증키값을 가져와야함")
print(e)
Init()
finally:
headers2= {'key' : key,'속성값':,'속성값'}
res = requests.get(Url+userId, headers=headers2)
if res.status_code==403:
print("인증키 만료로 재인증 요청")
Init()
headers2={'key':key,'속성값':'속성값'}
res=requests.get(Url+userId,
headers=headers2)
print(res.content)

'Programming' 카테고리의 다른 글

RoadMap  (0) 2021.11.11

참고 링크
https://www.cisco.com/c/en/us/support/docs/switches/nexus-9000-series-switches/200248-Configuring-Microsoft-Windows-Server-201.html

Configuring Microsoft Windows Server 2012 to provide DHCP services in an eVPN Scenario (VXLAN, Cisco One Fabric, etc)

Since the introduction of Virtual Extensible LAN (VXLAN) and Cisco One Fabric (formerly Dynamic Fabric Automation (DFA)) providing DHCP services has begun

www.cisco.com


시나리오
1. 하나의 네트워크 대역(VLAN도 한 개)에 DHCP 서버를 두고 범위(scope)를 할당
2. 여러 개의 네트워크 대역(VLAN 여러개)을 같은 네트워크(동일한 L3) 구간 내에 존재하는 DHCP서버를 통해 DHCP주소 할당하기
3. 한 개의 네트워크대역을 다른 네트워크 대역에 있는 DHCP 서버를 통해 DHCP 주소 할당하기
4. 여러 개의 네트워크 대역(VLAN 여러개)에 다른 네트워크 대역에 있는 DHCP서버를 통해 DHCP 주소 할당하기


[경험으로 얻어진 필수 상식]

1. 1개의 범위 할당시, DHCP서버는 (1) 같은 VLAN대역에 있어야하고, (2) 해당 범위 내의 IP주소를 보유하고 있어야 클라이언트들이 DHCP를 정상적으로 받아간다.

2. 2개 이상의 범위 할당을 하려고 DHCP서버에 범위를 2개 이상 설정해놓아도, DHCP서버와 다른 VLAN을 가진 애들은 DHCP서버로부터 DHCP 주소를 받아가지 못한다.

3. 이 경우 같은 네트워크 (L3) 내 다른 VLAN을 가진 클라이언트들이 DHCP 주소를 받아가려면 스위치의 VLAN 설정에서 DHCP Relay설정을 해주어야 정상적으로 IP를 받아갈 수 있다.


[추가적으로 경험한 내용]

4. 이젠 다른 네트워크 대역에 존재하는, 즉 라우터 밖으로 나갔다 와야하는 경우, 타 라우터 장비에 존재하는 DHCP서버에서 IP주소를 받아가려면 DHCP Relay설정만으로는 부족하다.

문제를 해결하기위해 Wireshark로 패킷을 까보았다. 목적지 서버까지는 DHCP Discover가 도달하지만, 서버가 보내는 DHCP Offer를 클라이언트쪽으로 스위치가 전달해주지 못한다. 출발지 IP가 상대 네트워크의 Gateway IP로 세팅이 되어있다보니 회신하는 과정에서 패킷이 클라이언트쪽으로 도달하지 못한다. (네트워크 전문가가 아니어서 원인은 잘 모른다)

5. 그래서 Loopback IP를 스위치에 설정해주었다.
어떤 약속된 IP자원을 소모해서 루프백 IP 하나를 스위치에 할당하고, 이제는 그 IP 가 서로 다른 네트워크 장비 간의 통신을 중개해주는 가교 역할을 하는 것이다.

6. 하지만 이 설정만으로 서버에서 만든 DHCP Offer가 클라이언트 PC까지는 전달되었는데, 서버는 최종적으로 ACK까 아닌 NAK를 보내게 된다. 원인은 나도 모르지만 Wireshark로 패킷을 까보면 Discover가 1초에 백개 이상 발생하며, DHCP서버 입장에서는 중복된 요청이 들어오므로 NAK를 뿌리는 것이었다. 해결방법을 찾기 위해 한참을 헤맸다. 결론은 DHCP서버 설정에도 Loopback IP 대역을 할당하는 작업을 해주어야 한다.(자세한 방법은 참고 링크를 보면서 따라 하면 된다.)

7. 그런데 Loopback설정만으로 두 개 이상의 VLAN 대역을 Relay하지 못했다. VLAN1에는 192.168.1.0/24를 할당하고 VLAN2에는 192.168.2.0/24를 할당했다고 하자. VLAN2에서 DHCP를 할당하는데 192.168.1.0대역을 가져가는 것이었다. 그래서 통신이 되지 않았다. 그 원인은 각각의 VLAN은 각각의 Loopback이 필요하기 때문에 Loopback을 VLAN 개수만큼 만들어 스위치에도 넣어주고, DHCP서버에도 만들어야 했다.

8. 마지막으로 IP 할당받을 대역1과 Loopback IP대역 1을 대범위(Superscope)로 묶어 주어야 했다. 각각의 대범위를 만들지 않으면 DHCP를 못가져감을 테스트를 통해 확인했다.

9. Option82라고 해서 스위치의 인증값을 DHCP서버 정책에 넣는 방법(링크참조)에 나와있지만, 운영 환경에서는 그 설정 없이도 잘 DHCP를 가져감을 확인하였다.

10. [번외] Windows DHCP서버2대를 failover 구성하고 C클래스 대역을 범위로 설정하면, 앞의서버는 대략 11~120의 IP 중 앞번호부터 할당하여 대략 11~30번대를 받아갔고 뒤의 서버는 130~250의 IP중 130~150 번대를 받아갔다. 또한 비활성화를 해두어도 주소 임대 현황은 서로 동기화가 되었다.



[결론]
1. 라우터->라우터 이동시 DHCP Relay설정뿐 아니라 Loopback IP 설정이 반드시 필요함.
2. VLAN이 두 개 이상일 경우, 각각의 VLAN에 대해 Loopback IP가 필요하고, 서버 DHCP에 Loopback IP값을 입력하려면 Loopback IP대역으로의 입력이 필요함.(그리고 Loopback IP끼리는 네트워크 범위가 겹치면 안됨)

구성 해보니 Loopback IP 대역은 서브넷 30비트가 제일 좋았음.
예를들어 두 개의 VLAN이 필요한 경우, Loopback은
192.168.100.12/30 , 192.168.100.16/30
으로 설정 해놓고
루프백 IP를
192.168.100.13-14
192.168.100.17-18
이렇게 스위치에 할당하면 문제가 없음.

AD GPO 정책은 Computer Configuration과 User Configuration 2가지가 있다.

보통 User Configuration을 설정하고 해당 GPO를 Computer가 모여있는 OU에 Link Enable 해도 사용자가 사용할 때 User Configuration 정책이 정상 작용되는데, 그 이유는 GPO의 Security Filtering과 Delegation에 Authenticated Users가 들어 있기 때문에, 운영자는 별로 신경 쓰지 않아도 되는 것이다.

그렇다면 어떤 GPO를 사용자별로 편하게 넣었다 뺐다 하는 방법이 있을까?

1. 특정 OU에 GPO를 Link 하고, OU에 User를 넣었다 뺐다 하면 gpupdate시 바로 정책 적용된다.
하지만 매번 번거롭다. 그렇다면?
2. 특정 GPO를 적용받을 대상이 User/Computer가 아닌 Group으로 설정하고, 그 Group에 User를 Member로서 넣었다 뺐다 하면?

그래서 2의 아이디어에 착안해서
1) (dsa.msc)특정 OU에 Group을 추가하고 Group 안에는 User를 Member로 넣음
2)(gpedit.msc) 그 OU에 GPO를 Link Enable 정책 적용!
결과 : 아무 변화도 일어나지 않았다.


이유
OU안에 있는 사용자/컴퓨터만 정책을 직접 받는 것으로 이해했다.
그래서 문의결과
Security Filtering을 사용하는 방법을 알게 되었다.
GPO의 Scope 탭을 보면, Links와 Security Filtering 두 가지 메뉴가 있는데,
1. Security Filtering에 Authenticated Users를 제거한 후 내가 적용하고자 하는 Group만 넣어준다. (Authenticated Users지울때 경고 메시지가 뜨는데 확인 눌러주면 된다.)
2. Delegation 탭으로 가면 Authenticated Users가 없어지고, 내가 추가한 Group이 Read (from Security Filtering)으로 권한이 들어가 있는 것을 볼 수 있다. 여기서 Add를 누르고 Domain Computers를 추가한다. 이 때 Permissions를 Read로 줄 것인지, edit setting 할 것인지 선택해야하는데, 그냥 Read를 선택한다.
간단히 적용!

!! 물론 Security Filtering을 설정하지 않은 채(Authenticated Users만 있고) Delegation에서 원하는 Group을 넣고 권한(Allowed Permission)을 custom으로 설정하여 가져갈 수도 있다.
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/dn789195(v=ws.11)

Delegate Permissions for Group Policy

Delegate Permissions for Group Policy 08/31/2016 9 minutes to read In this article --> This topic describes procedures for an administrator to delegate permissions to others using the GPMC so that they can perform some Group Policy administrative tasks. In

docs.microsoft.com

Delegation -> Advanced -> Advanced에 들어가서 Deny와 Allow를 여러 번 선택하면 Access권한이 Special로 변하게 되고, 저장하고 나오면 Delegation탭의 Allowed Permissions에는 Read -> Custom으로 바뀌게 된다. 이때 다시 Custom -> Read나 Edit Settings로 바꾸면 설정값이 다 날라가므로 주의가 필요하다.

★해당 정책 응용 : Deny정책을 만들어 모든 사용자에게 적용 한 후, Deny를 예외 처리 할(즉 정책을 사용할) 사용자는 Group을 만들어서 Member에 추가하는 식으로 운영이 가능하다.
Delegation에 그 Group을 추가 하고, 권한을 Advanced-Advanced에 가서 Deny - Apply group policy를 설정해 주면 된다. (그리고 Read 외에 나머지 권한은 혹시 모르므로 Allow - Modify,write에 관한 모든 권한은 쳬크하여 넣어준다.)
그러면 Deny / Apply group policy , Allow / special로 들어가며 delegation에는 custom으로 들어가게 된다.


그러면 본론으로 돌아와서 1. Security Filtering에 내가 원하는 Group 추가 2. Delegation에 Domain Computers Read 권한 부여 3. OU에 해당 정책 적용의 순으로 원하고자 하는 바를 적용할 수 있다.

1. OU에 Computers가 GPO를 적용받는 경우
1-1 Group Member의 경우 - Authenticated Users와 동일 동작. 즉 Link Enable/Disable 여부에 따라 gpupdate시 바로 적용/미적용
1-2 Group Member가 아닌 경우 - 해당 정책을 없는 것처럼 동작. 즉 Link Enable 후 gpresult로 확인해도 해당 정책은 없는 것처럼 보고되지 않는다.

2. OU에 Users가 GPO를 적용받는 경우
1-1 Group Member의 경우 - 어느 컴퓨터에 접근하든 정책이 적용된다.
1-2 Group Member가 아닌 경우 - gpresult상으로는 정책을 성공적으로 적용한 것으로 보고되나, 거부된 GPO에도 항목이 등재되며 거부된 이유로는 액세스 거부(보안 필터링) - 결과적으로 안 됨

3. OU에 Group을 넣고 GPO를 Link Enable한경우 - 아무런 결과가 나타나지 않음
결국, Group은 GPOLink랑 아무 관련이 없음

4. (중요) Group의 Member인지 여부는 컴퓨터 부팅후 첫 로그인 할 때 결정됨!
다시 말하면 로그인 이후 Group의 Member를 수정하고 아무리 gpupdate 를 날려봐도 GPO가 적용되지 않음. 이러한 특성 때문에 많이 헷갈렸다. 아무튼 Member 변경 후 해당 GPO를 적용 시키려면 무조건 리부팅을 해줘야 한다.
4-1 첨부터 그룹 멤버로 인식된 경우 멤버를 제거해도 계속 그 정책을 반영한다.
4-2 첨부터 그룹 멤버로 인식되지 않은 경우 리부팅 전까지는 해당 GPO를 적용시킬 방법이 없다.

추가로 알게 된 사실 - Delegate에서 custom권한을 제거하면 Read 권한으로 강등되며, Read(from Security Filtering)을 제거하면, Scope의 Security Filtering 에서도 해당 객체는 지워진다.

1. 기본적인 SecureString 사용법

https://stackoverflow.com/questions/37662937/storing-credentials-to-run-powershell-script-in-php-application-remotely

 

Storing credentials to run PowerShell script in PHP application (remotely)

I'm running a Windows 2012 R2 server with XAMPP (php/mysql/apache) and PowerShell v3. For the past couple of months, my code has been working just fine to store and retrieve an encrypted password ...

stackoverflow.com

 

2. SecureString을 PHP에 올렸다가 실패한 어느 뉴비의 자문자답

https://stackoverflow.com/questions/51365603/using-exec-to-run-powershell-script-hangs-if-i-try-to-set-credentials

 

Using exec to run PowerShell script hangs if I try to set credentials

Firstly I apologise but I am pretty new to PHP and PowerShell, we all have to start somewhere! I am creating a utility where everyday IT tasks can be performed from a central web based console. I...

stackoverflow.com

 

3. 우리는 해냈다 늘 그랬듯이

stackoverflow.com/questions/23699500/convertto-securestring-gives-different-experience-on-different-servers/23700513

 

ConvertTo-SecureString gives different experience on different servers

I am running into an issue creating a Credential Object from an XML File on a remote server. Here is the code I am using to test XML File stackoverflow.com

 

 

먼저, 이것을 하려는 목적은

1. 파워쉘기반 운영서버에 (감히) WEBWAS를 돌릴 수 없다.

2. 따라서 운영서버 옆에 나만의 WEBWAS를(다른 운영중인 윈도우서버안에) 구축하여, Remote Powershell로 제어를 하고 싶었다.

3. 웹서버는 IIS를 사용하고, PHP는 FastCGI로 구성했다.(feat 구글링)

4. 간단한 원리는 PHP가 되는 서버에서 Remote Powershell로 운영서버에 Powershell을 날려서 데이터를 가져오고 그것을 Web으로 쏘는 것이다. 그러려면 exec_shell 메서드가 필요하다.

[트러블슈팅1] PHP의 exec_shell 메서드를 사용하여 서버 자원에 접근하려면 PHP가 설치된 서버의 cmd.exe에 IIS_IUSRS에 Read 및 Execute 권한이 필요하다. (Users의 권한을 보안상 제어하는 경우)

5. 리모트 파워쉘을 다른 클라이언트에서 접근하려면 수동으로 패스워드를 입력해서 사용한다. 하지만 자동화를 위해서는 반드시 서버의 인증 정보를 가지고 있다가 원격 접속시 사용해야 한다.

6. 그래서 사용하는 방법이 인증 정보를 만들어 명령을 전달하는 방법이다. 서버의 $id와 (반드시 SecureString으로 변환된) $passwd를 가지고 인증정보($cred)를 만든 후(PSCredential), 그 인증정보를 가지고 $session정보를 만들면 된다.(New-PSSession) 그리고 마지막으로 Invoke-Command를 통해 파워쉘 명령을 Target Server에 날린다.

정리하면

1. $passwd를 SecureString으로 변환한다.
2. $credential = New-Object PSCredential $id, $passwd (SecureString형태)
3. $Session = New-PSSession -computername $TargetServer -credential $credential
4. Invoke-Command -session $session -filepath "실행하려는파워쉘.ps1" -argumentlist "인자값"
  ※ 필요한 데이터 $id, $passwd, $TargetServer, 실행하려는파워쉘 및 인자값

 

[트러블슈팅2] PHP의 exec_shell이 SecureString 처리를 못함

$password를 SecureString으로 변환하는 방법은 두 가지가 있다.

1. 서버에 저장된 평문패스워드를 불러온 후(Get-Content)
2. $passwd = ConvertTo-SecureString -AsPlainText -Force -String $plainPW(평문패스워드)
1. 서버에 저장된 암호화된 패스워드를 불러온다. (이는 ConvertFrom-SecureString을 거친 후 서버에 난수로 저장됨)
2. $passwd = ConvertTo-SecureString -String $encryptedPW (암호회된 패스워드)

 

그런데 운영자 관점에서 패스워드 유출이 꺼려지니 당연히 암호화된 패스워드를 사용하는 두 번째 방법을 활용하게 된다. 그런데! PHP서버 내부의 cmd에서 돌리면 너무나 잘돌아가던 파워쉘이 exec_shell에만 들어가면...실행을 못한다.

편의상 $pass를 평문암호, $passwd를 SecureString으로 encrypted된 암호라고 하면, 아래의 두 경우 모두 cmd에서는 결과값을 가져오는데, php에서는 결과값을 가져오지 못한다.

$pass = ConvertFrom-SecureString -SecureString $passwd
echo $pass #실패
$passwd = ConvertTo-SecureString -String $encryptedPW
echo $passwd #실패

그래서 그 이후의 $credential을 못 만들어서 php 자체를 못 쓰게 된다는 것.

이러한 문제 때문에 나는 계속 첫번째 방법인 평문패스워드를 -AsPlainText로 사용하였으나 이는 커다란 보안 취약점이다. 그래서 찾아보던 중 오아시스같은 3번째 링크에 다음의 설명을 발견했다.

When you use the command ConvertTo-SecureString it encrypts the plaintext password with the encryption key on the local machine, under your user account

즉, 내가 이해하기로는 SecureString을 만들때 반드시 key값이 필요한데, key값을 별도로 명시하지 않으면, local machine에 있는 user account를 key값으로 쓴다는 것이고, cmd로는 잘 돌던게 php에서는 안 돌아가는 이유는! php가 shell_exec 메서드로 수행하는 user계정이, cmd에서 만든 ConvertFrom-SecureString를 제대로 처리할리가 없던 것이었다.

그래서 key를 별도로 쓰면 해결되는 문제였다. 다음과 같이 해결하였다.

<인코딩><패스워드를 난수화하여 서버에 저장>
$key = (3,4,2,3,56,34,254,222,1,1,2,23,42,54,33,233,1,34,2,7,6,5,35,43)
$plainPassword = "평문패스워드"
$securePassword = $plainPassword | ConvertTo-SecureString -AsPlainText -Force  #암호화된 패스워드
$securePasswordKey = ConvertFrom-SecureString $securePassword -key $key   #암호화된 패스워드를 key로 난수화
Set-Content -Path "c:\패스워드.txt" -Value $securePasswordKey 
<디코딩><난수화된 패스워드를 불러와서 사용>
$key = (3,4,2,3,56,34,254,222,1,1,2,23,42,54,33,233,1,34,2,7,6,5,35,43)
$pass = Get-Content -Path "c:\패스워드.txt"
$passwd = ConvertTo-SecureString -String $pass -Key $key

이후 $cred, $session 잘 만들어진다.

tasklist /FI "IMAGENAME eq notepad.exe"
프로세스가 실행중이든 실행중이지 않든 쿼리 결과에 대한
%errorlevel%값은 0이더라.

stakoverflow에서
how to check if a process is running via a batch script 참조한결과
find명령어를 추가하여 errorlevel을 조정할 수 있다.

tasklist /FI "IMAGENAME eq notepad.exe" 2>NUL | find /I /N "notepad.exe">NUL

if %ERRORLEVEL%  == 1(
goto INSTALL
)

이 방법으로 PaTray.exe가 프로세스로 떠 있지 않는 이슈를 해결하였다.


카톡봇 입문

Programming/카톡봇 2019. 9. 20. 22:53 Posted by ­행복

1. 자바스크립트 기반으로 알려져있지만

진짜 기능을 위한 Api를 써서 다양한 기능을 하려면 자바를 알아야한다.

(Rhino엔진)

2. eval 함수를 통해 카톡상에서 자바스크립트를 인터프리터 방식으로

(크롬 자바스크립트 콘솔창이 아니더라도)실시간 확인할수 있다!

3. try-catch 구문을통해 스크립트 오류 없이 계속 유지할 수 있다!

2,3의 조합 소스코드

const scriptName="hello.js";

function response(room, msg, sender, isGroupChat, replier, ImageDB, packageName, threadId){

    if(sender=="abc")

    {

    try{

        replier.reply(eval(msg));

    }

    catch(e){

        replier.reply(e+"\n에러난 코드 줄 :"+e.lineNumber);

     }

   }

}

 

4. 카톡 함수가 대화보다 빠를 때, 대화를 기다려주자

java.lang.Thread.sleep(1000);

'Programming > 카톡봇' 카테고리의 다른 글

파이썬 인코딩 개삽질기  (0) 2021.05.17

드디어 3개월에 걸친 나의 고민을 타파해서

블로그에 글을 안 남길 수 없다.

카카오톡뿐 아니라 그동안 개행문자때문에 데이터 가공에 고생했던 나날들이 떠오른다.

얼마나 미개하게 했었는지 서술한다. 카카오톡 대화를 내보내기 하여 KakaoTalkChats.txt을 보면

2019년 7월 2일 오전 7:52, 아이디 : 네~ 감사합니다~^^

그리고 항상 잘 읽고 있습니다

 

엔터키가 눌려진 대화를 저장하기 위해 배치 스크립트를 돌리려면

이거 처리하기가 너무 골치가 아픈거라...

방법1) 배치파일로 문서 파싱하는 툴을 써서(필자의 경우는 오토핫키)

임시 변수에 현재 행의 데이터 중 시간과 아이디를 임시 저장한다.

그리고 다음 행의 데이터를 읽을 때, 아이디의 특수한 값이 감지되지 않으면

'이전 날짜값저장변수+데이터'를 새로운 텍스트에 저장한다.

그러면 가공된 데이터는 아래와 같이 변경된다.

2019년 7월 2일 오전 7:52, 아이디 : 네~ 감사합니다~^^

2019년 7월 2일 오전 7:52, 아이디 : 그리고 항상 잘 읽고 있습니다

 

이런 미개한 방법으로 수백~천라인의 데이터가 리패키징 되는 과정을 처리하며 PC자원과 시간의 낭비를 했다.

이과정은 DB에 입력할 라인을 무수히 증가시켰지만,

일단 변환된 텍스트를 db에 밀어넣는건 개꿀이다. (하지만 DB에 밀어넣을때도 년,월,일,ID,내용 파싱하고 insert할 값으로 변환하는데 PC자원을 사용하므로 이중 자원의 소비를 했다)

이 방법의 가장 큰 장점은 PHP로 Web에 출력할 때, 뉴라인을 고려하지 않아도 된다.

<td>테그를 써서 라인이 구별되는 편리함 때문에 이 방법을 고수해왔다.

(사실 더 미개한 이야기지만 매일의 대화를 저장한 것을 날짜.html 파일로 만들어 보관하고 있었다.

데이터 서칭은 포기한 셈. 그러다가 추후 피땀흘려 mysql과 php연동을 웹상에서 하게 되었다.)

 

매일 카톡을 실행하고 대화내용 내보내기를 해서 DB에 넣는 노가다 뛰는것도 힘들었지만, 카카오톡 유저들이 말하고 삭제하면 삭제된 메시지로 기록된다. 이에 노이로제가 걸려 다음의 방법을 생각하게 된다. 그런데 이 마저도 KaKaoTalkChats.txt 를 별도로 불러와서 '삭제된 메시지'를 손으로 끼워맞추며 천문학적인 시간을 데이터 복원 작업에 쓰는 미개함을 보여주었다. 그러다가 문득 든 생각.

방법2) 카톡봇을 이용해서 데이터를 만든다.

아예 DB에 밀어넣기 쉬운 방법으로 '날짜','ID','내용'으로 저장하겠다.

그 결과는 다음과 같다. 그러나!!!!!

'2019-08-05 08:42:53', '아이디', '오늘도 즐거운 하루되세요~

올여름 잘보내세요~~^^'

이 지랄과 같이 되었다. 그렇다 나의 불찰...

그렇게 방법1에서 오토핫키까지 쓰며 고민했던 내용을 고스란히 잊어버리고 같은 실수를 반복했다.

개행문자가 없으면 정상적으로 '날짜','ID','내용'이 저장되겠지만..

개행문자가 있을때는

첫 줄이 작은따옴표를 만나지 못하고 오류, 두번째 줄도 오류.....결과는 두 값 모두 입력안됨

그래서 포기하고 있었는데, 생각해보니 입력받는 내용에

방법2-2) 개행문자를 Replace해주면 되겠네?

하지만 javascript상에서도 \n은 개행문자로 인식한다 → \\n으로 넣으면 비로소 \n으로 텍스트가 저장된다.

추가적으로 ' 문자와 \ 문자는 mysql상에서 인식을 못하니 혹시나 만나게 될 경우 두번 넣어준다.

(\문자는 정규식도 잘 안먹어서 그냥 포기)

            a=msg.replace(/\n/g,'\\n').replace(/\'/g,"\'\'")

'2019-08-05 08:42:53', '아이디', '오늘도 즐거운 하루되세요~\n올여름 잘보내세요~~^^'

이렇게하면 DB엔 완벽히 개행문자로 들어가고 출력도 된다.

하지만 마지막문제, 왜 Web상에서는 개행문자가 적용이 안되고 공백문자로 space로 나올까?

오래지않아 view-source로 그 원인을 알 수 있었다. 진짜 html 소스코드에 개행이 되어 있었다!

오랜 경험으로 html에서 개행문자는 <br></br>임을 알고 있다!

그러면 php 작성을 손봐야 하는구나!

검색어는 php new line to br

http://docs.php.net/manual/kr/function.nl2br.php

 

최종 성공

sql쿼리를 돌려 얻은 값을 nl2br함수로 한번 더 감싸줌

echo nl2br($content);

이제 맘 편히 데이터를 저장할 수 있게 되었다.

더 이상 불편한 행동을 하지 않아도 된다.

너무나도 행복하다.

'Programming > WEBWASDB' 카테고리의 다른 글

Powershell SecureString을 PHP에서 사용하려면  (0) 2020.06.11