'aws'에 해당되는 글 16건

  1. 2020.12.18 Software | AWS Certified 자격증 취득기 - 5 3
  2. 2020.07.26 AWS | Lightsail 과 Outline 이용하여 VPN 만들어 보기 9
  3. 2020.07.25 Wowza | AWS 에 Wowza 설치해 보기
  4. 2020.06.28 Software | Windows 10 Pro 와 Office 2019
  5. 2020.06.17 Software | AWS Certified 자격증 취득기 - 4 8
  6. 2020.04.23 Software | Bing webmaster tools 사용기
  7. 2020.04.22 Software | NAVER Analytics 사용기
  8. 2020.04.21 Hardware | ESP32 NTP Server 이용한 시간 맞추기
  9. 2020.04.18 Hardware | ESP32 Deep sleep 알아보기
  10. 2020.04.16 Hardware | ESP32 Cryptographic HW 가속 확인해 보기 2

Software | AWS Certified 자격증 취득기 - 5

|

이 포스트는 AWS 인증 자격시험 다섯 번째인, AWS Certified Big Data - Specialty 실패기가 되겠습니다.


* Exam Name - AWS Certified Big Data - Specialty

* Exam Code - BDS-C00

* Online Class - Exam Readiness: AWS Certified Big Data - Specialty (Digital)


이 시험준비에 앞서 "Cloud Practitioner", "Solution Architect - Associate", "Solution Architect - Professional",

그리고 "Developer - Associate" 도전기는 아래 포스트를 참고해 주세요.


* Software | AWS Certified 자격증 취득기 - 4

https://chocoball.tistory.com/entry/Software-AWS-Certified-4


* Software | AWS Certified 자격증 취득기 - 3

https://chocoball.tistory.com/entry/Software-AWS-Certified-3


* Software | AWS Certified 자격증 취득기 - 2

https://chocoball.tistory.com/entry/Software-AWS-Certified-2


* Software | AWS Certified 자격증 취득기 - 1

https://chocoball.tistory.com/entry/Software-AWS-Certified-1


2019년부터 시작한 IT 자격증 취득 여정 중, 처음으로 실패 했습니다.

시험은 2020년 6월 이었습니다만, 한 동안 충격에서 허우적여 2020년을 보내는 마지막 달인 12월에 와서야 내용을 정리하게 되었습니다.




1. 소개

지금은 Data Analytics 로 변경되면서, 리타이어 되어 버렸지만 Big Data - Specialty 를 취득하기 위한 과정 정보 입니다.


AWS 가 소개하는 본 시험에 관한 정보 입니다.


AWS_Certified_Big_Data_Specialty_Blueprint.pdf

AWS_Certified_Big_Data_Specialty_Exam_Guide_v1.2.pdf

AWS_Certified_Big_Data_Specialty_SampleExam.pdf




2. 자료


시험을 보기 위해 준비 했었던 자료들을 모아 봤습니다.

Big Data 는 여러 기술 및 AWS 서비스로 구성되어 있으므로, FargateKinesis 강의도 들었습니다.


* Exam Readiness: AWS Certified Big Data - Specialty (Digital)

https://www.aws.training/Details/Curriculum?id=21332

AWS_BDS-C00_20200608_chocoball_part1.pptx

AWS_BDS-C00_20200608_chocoball_part2.pptx


* Big Data Technology Fundamentals Online (Released 2016)

https://www.aws.training/Details/Curriculum?id=11070


* Introduction to AWS Fargate

https://www.aws.training/Details/Video?id=16623

AWS_Introduction_to_AWS_Fargate_20200615_chocoball.pptx


* Introduction to Amazon Kinesis Firehose

https://www.aws.training/Details/Video?id=16359

AWS_Introduction_Amazon_Kinesis_Firehose_20200615_chocoball.pptx


* DUMP

BDS-C00 V13.95.pdf

AWS-Big-Data-Specialty V13.75.pdf


시험 자체가 2020년 6월 말에 없어지다 보니, 준비할 시간이 부족해서 8만원을 들여 처음으로 dump 를 구입했습니다.




3. 시험 등록


Retire 되기 전, 마지막 날인 6월 30일 시험 등록.



시험 보기 전날 Practice 시험을 쳐 봤습니다.

결과는 50%... 너무 무리하게 준비한 결과 입니다. 아직 Presto 가 뭔지, Glue 가 뭔지 잘 모르는 상태.



시간이 없었지만, 일단 무리하게 진행합니다.




4. 시험 당일


새벽 1시까지 공부 하고, 다른 시험때 처럼 5시에 일어나 목욕재계 합니다.

그리고, 무거운 머리를 이끌고 시험장으로 향합니다.



윗 사진을 왜 찍었는지 잘 기억이 나지 않지만, 컨디션 좋아지도록 고속 충전기 같은게 있으면 좋겠다... 라고 생각하면서 찍은 듯 합니다.

아침 일찍이지만 부지런히 출근하는 사람들로 벌써 북적북적.



마지막 에너지 충전을 위해, 항상 그랬던 것 처럼 콜라 500ml 구입.



오늘 시험장은 처음으로 사용해 보는 종로 Soldesk.



건물이 낡아서, 환경은 그리 좋지 않습니다.



생소한 공간... 화장실이 매우 청결하지 않았던 것으로 기억합니다.



다행히 공부할 수 있는 공간이 있어서, 마무리 스파트 걸어 봅니다.



운동 경기에 나갈 때 먹는, 단백질과 열량 보충제, 그리고 오븐에 구운 도넛 처묵처묵 하면서 라스트 스파트.



시간이 되어 접수처에 등록하고 시험 시작. 두둥!





5. 결과


처음에는 믿지 못했습니다. 내가 시험에 떨어졌다는 것을...

"Unfortunately... " 로 시작하는 문구가 보이는, 처음 접해보는 화면은 매우 어색했습니다.


5분동안 손까락 까닥 하지 않고 석고상이 되었습니다. 5분정도 지나서야 사태를 파악하고 나오는 단발마... "끙..."

정말 얼굴과 온 몸에서 핏기가 빠져 나가는 느낌이었습니다. 아니 "왜"? 내가 떨어진거야?



당연하죠. 지식이 너무 얇았으니까. 열씸히 공부 했다고는 하지만, 단순히 외워서 하는 방식은 제가 재일 못하는 방법.

무조건 왜우려고만 했던 제 자신을 반성했습니다.


Big Data - Specialty 시험이 없어지는 것에 마음이 급했고, 없어지면 못 따게 되는 시험을 자랑하고 싶은 마음에 무리 했습니다.

그랬습니다. 떨어졌습니다.




6. 사무실로...


시험을 마치고 출근할 때 찍은 사진들 입니다.



그 때 당시의 마음을 표현하듯, 뭔가 힘이 없네요.



하늘도 우중충.



꽤 마음 아팠습니다. 그리고 날아가는 돈도...





FIN


AWS 파트너사로 직장을 옮겨, 7개월 정도 지나고 되돌아 보니, 얼마나 어리석게 준비했는지 이해가 됩니다.

어느 정도로 모르는 상태로 무모하게 시험을 봤었는지.


단순히 외우는 것을 잘하는 사람들은 문제 없을지 모르나, 저는 단순 암기에는 소질이 없는지라,

이런 식의 도전은 의미가 없다는 것을 다시금 알게 되었습다.


그 후, 정신 차리고, 다음 시험으로 SysOps Administrator - Associate 에 도전하게 됩니다.


And

AWS | Lightsail 과 Outline 이용하여 VPN 만들어 보기

|

인터넷 상에서의 정보는 투명해야 하며, 그의 접근이 자율적이며, 접근자의 수준도 같이 높아져야 한다고 생각합니다.

인터넷에 의한 인류의 진화라고 저는 생각합니다.


정보 접근에 있어, 국가 단위로 제한을 가하는 단체들이 있습니다. 진화할 수 있는 기회를 박탈한다고 봅니다.

그래서인지 예전부터 개인 VPN 에 관심이 있었습니다.


VPN 계열에서는 OpenVPN 이 단연 유명한 듯 보입니다. 그렇지만, 설정이 많이 복잡하더군요.

뭐 좋은 것이 없을까 하던 중, AWS 서비스 중에서 쉽게 서버/시스템 구축이 가능한 서비스가 있어, VPN 구축에 활용해 봤습니다.



본 포스트는 제가 조사하여 시행 착오를 겪으며 만들어 낸 내용이 아니라, 전적으로 아래 블로그를 따라한 내용 되겠습니다.

좋은 글을 작성해 주신, 아래 글의 작성자님께 감사의 말씀 드립니다.


* AWS와 Outline으로 나만의 VPN 서버 만들기

https://brunch.co.kr/@flown/21




1. Lightsail - Instance


AWS 서비스는 물리적인 서버를 구매, 설치하고 인터넷 계약을 하지 않아도 5분 안에 서버를 만들 수 있게 서비스를 제공합니다.

이런 것을 클라우드 서비스라고 합니다. 내 앞에 존재하지 않지만, 인터넷 상으로 시스템과 서비스를 만들어 주는 서비스 이죠.

잘 모르겠고 안보이지만, 실제로 존재하는 뜬 구름같이...


AWS 서비스 중에서도 EC2 라는 것이 있는데, CPU / Memory / Disk 등을 정하면 뚝딱 서버를 만들어 주죠.

다만, EC2 라도 접근 제어라든지, 보안, 네트웍 구성 등, 손이 조금 갑니다.


워낙 클라우드 서비스를 접하게 되는 사람들이 많아지고, 모든 사람이 전문적인 지식을 기대하기 어렵다 보니,

더 쉬운 방법으로 클라우드 서비스를 올릴 수 있는 "Lightsail" 서비스를 AWS 에서 출시 하게 되었습니다.



AWS console 에서 Lightsail 을 선택합니다. 오후에 접속하니 Good afternoon! 이라고 인사하네요.

오전에 접속하면, Good morning! 이라고 합니다. "Create instance" 로 서버/서비스 생성을 시작합니다.



서버의 위치를 정합니다. 한국에 서버를 설치해야, 내가 접속하는 PC 와 속도가 빠르기 때문에 Seoul - ap-northeast-2 를 선택합니다.



Availability Zone 은, 미리 선택된 Zone A - ap-northeast-2a 그대로 놔 뒀습니다.

OS 는 Linux/Unix 를 선택하고, Ubuntu - 18.04 LTS 를 선택.



그 다음으로, 어떤 type 의 서버를 선택할 것인지를 정합니다.

VPN 은 CPU / Memory 는 중요하지 않으나, data 전송량이 관점이므로, 3TB 를 선택했습니다.

저는 동영상 스트리밍에도 사용할 것이라... 어험.


VPN 은 중간 단계에서 중계해주는 역할이므로, 3TB 를 선택하면, 한 달동안 1.5TB 데이터를 사용하겠다의 의미가 됩니다.

그래도 10 USD 밖에 하지 않습니다. 정말 저렴한거죠.





2. Lightsail - Networking


다음으로, 고정된 IP 를 사용하기 위해, "Create static IP" 를 선택합니다.

내가 사용할 때 마다, 변경된 IP 를 매번 확인하고 접속한다면 여간 불편하지 않을 수 없습니다. 고정 IP 를 사용합시다.



IP 는 공공제 이지만, 경쟁하면서 사용하는 유한한 자원이므로, 사용하고 있으면 무료이고, 사용하지 않으면 돈을 냅니다.

사용하면 돈을 내는 일상 생활과는 정 반대 개념입니다.



Instance 이름과, 고정 IP 에 대한 별칭을 정하면 끝입니다.



"Create" 를 누르면 고정 IP 하나가 할당 됩니다.





3. Lightsail - SSH


Instance 에 접속하기 위한 SSH 설정 입니다.

다른 EC2 접속 할 때, 사용하는 ec2-user 유저가 아니라, ubuntu 입니다.



Public Key 를 이용한 SSH 프로그램을 통한 접속이 아니라, "Connect using SSH" 브라우저에서 바로 연결할 수 있습니다.



저는 SSH 어플을 이용해 접속하는 것을 선호하는 지라, 다운로드 한 SSH Key 를 가지고 접속했습니다.



위의 과정이 끝나면, 서버가 하나 만들어 졌습니다. 이쪽 용어로는 인스턴스 하나가 만들어 진거네요.





4. Outline - Manager


VPN 서버의 껍때기는 만들어 졌으니, VPN 전용 어플을 서버에 깔아줘야 합니다.

Outline 이라는 VPN 서버를 사용합니다. 아래 사이트에서 Outline - Manager 를 다운로드 받습니다.


* Outline by Jigsaw

https://getoutline.org/en/home



설치파일을 받으면 실행 시킵니다.



이 Outline - Manager 는 원격에서 VPN 서버를 모니터링 하고 관리하기 위한 어플 입니다.



Outline 은 언론 기관과 언론인이 안전하게 인터넷에 접속할 수 있게 하기 위해 만들어 졌다고 하네요.

어느 한 나라가 생각나는 대목입니다.



실제 클라우드 상의 서버에서 돌아갈 패키지를 선택하기 위해, 우선 클라우드 업자를 선택합니다.

이미 Amazon Lightsail 이 기본으로 제공되고 있군요. GCP 버전도 있습니다.



Amazon Lightsail 을 선택하면, Lightsail 에서 동작하는 VPN 프로그램을 자동으로 설치하게 도와주는 스크립트를 보여줍니다.




$ sudo apt update
$ sudo apt upgrade

$ sudo bash -c "$(wget -qO- https://raw.githubusercontent.com/Jigsaw-Code/outline-server/master/src/server_manager/install_scripts/install_server.sh)"


OS 업데이트 후, 위의 스크립트를 실행하면, Docker 형식으로 VPN 서버가 깔리게 됩니다.



위 화면에서 Y 를 누르고 설치를 진행하고 마무리 합니다.



설치 완료 후, 녹색 부분을 카피해서 Outline Manager 화면으로 돌아와 "여기에 설치 출력을 붙여넣으세요." 에 붙여넣기 합니다.

또한, 포트 번호을 기록해 둡니다. 하나는 Outline Manager 용 port 정보이고, 다른 하나는 VPN 트래픽용 port 정보 입니다.


저의 경우는 Manager - 49742 / TCPVPN traffic - 11383 / TCP, UDP 였습니다.

위의 스샷처럼 Lightsail 의 Firewall 에 등록해 줍니다. 


그러면, 아래처럼 Outline Manager 에 Lightsail 에 설치한 VPN 서버가 등록되고, 모니터링이 가능하게 됩니다.

"실험" 부분은 새로 나온 기능처럼 보이며, 3TB 전송 가능한 Lightsail instance 를 설치했지만, 양방향 통신이므로, 1.5TB 를 설정해 놓습니다.

이 수치에 도달하면 자동으로 VPN 기능이 정지될 듯 합니다.





4. Outline - Client


서버가 준비 되었으니, 이제 PC 에서 VPN 접속을 위한 client 를 설치해 봅니다.

Outline Manager (Server) 에서 "내 액세스 키 - 기기 연결" 을 클릭합니다.



하나의 VPN 서버에 여러명이 동시에 사용할 수 있는군요.



액세스 코드 복사하기를 클릭합니다.



키를 받았으니, 이 키를 이용하여 VPN 서버에 접속하는 클라이언트만 있으면 됩니다.



"이 기기 연결하기" 를 클릭하면, 자동으로 클라이언트를 다운로드 받는 페이지로 점프하게 됩니다.



설치파일을 다운받고 설치해 줍니다.



엇!!! OpenVPN ?


그렇습니다. 서버도 클라이언트도 OpenVPN 이 코어인 어플들이었던 것이죠.

OpenVPN 을 날것으로 시작하려면, 많이 복잡합니다. 이 과정들을 docker 나 어플 패키지로 단순화 시켜준 것이 Outline 이었던 것이죠.



언론 탄압이 가해지는 곳에서도 사용할 수 있게끔 만들어 진것 같네요.



일부 기술적인 정보 외에는 개인정보를 가져가지 않는다고 합니다... 만,

가져가도 상관 없습니다. 어느정도 개인 정보는 이미 공공제가 된지 오래...



어플을 깔면, 아까 복사한 액세스 키가 자동으로 감지됩니다. 최신의 COPY 명령어 결과를 찾아보는 듯.



Outline Client 가 서버를 인식하고 등록이 완료 되었습니다.





5. VPN 서버에 연결


Outline Client 에서 "연결" 을 통해, Lightsail 에서 동작하는 우리의 VPN 서버에 연결합니다.


Google 사이트를 통해, VPN 을 켰을 때, IP 가 어떻게 나오는지 확인해 봤습니다.



원래 집이나 사무실에서 할당받았던 IP 가 아니라, VPN 서버의 IP 로 변경되고, 국가/ISP 에서 막아 놨던 사이트들 접속이 원활해 졌습니다.




FIN


마지막으로, 기술을 공유되어야 한다는 GNU 선언문의 일부를 인용하여 마무리 합니다.


GNU, which stands for Gnu's Not Unix.


'Cloud' 카테고리의 다른 글

Wowza | AWS 에 Wowza 설치해 보기  (0) 2020.07.25
And

Wowza | AWS 에 Wowza 설치해 보기

|

오랜만에 Wowza 를 linux 환경에 설치해 봤습니다.





1. AWS Marketplace


클라우드 중에서 요즘 대세인 AWS 의 instance 에 설치해 봅니다.


그냥 EC2 instance 에 linux 를 깔고, Wowza 파일 받아서 설치할 수도 있으나, AWS 서비스에서 제공하는 3rd party 솔루션 제공 방법인 Marketplace 를 사용해 봅니다. 돈은 조금 더 들지만, 편합니다.



아무래도 Wowza 는 License 지불을 해야 하므로, Marketplace 에서는 "구독" 으로 취급됩니다.

한달에 기본 사용료 15 USD + EC2 시간당 사용으로 과금됩니다.



License 사용료가 한달에 15 USD 인 셈이군요.





2. Wowza 시작


Marketplace 를 통해 설치한 Wowza 인스턴스는 5분정도 있으면 생성이 됩니다.

맙소사... 너무 편해. 물리적인 서버도 필요 없고, OS 설치도 없었을 뿐더러, Wowza 어플리케이션 설치도 하지 않았지만, 생겼습니다.



EC2 Instance URL 로 접속하면, 위의 시작 페이지가 뜹니다. Next 눌러 줍니다.



처음 시작했으니, admin 의 이름과 암호를 넣으라고 합니다.

ID 는 wowza 이고, 비번은 instance ID 입니다.



EC2 instance 관리 화면에서 Wowza 서버의 Instance ID 를 카피해, 암호로 넣으면 됩니다.



Live 를 사용할 것이라면 게시지점을 넣으라고 합니다. URI 정보입니다만, 나중에 설정하면 되니, 과감하게 패스.



10여분만에 Wowza 한대 추가요~.



응?!!! 4.8.5 버전으로 업데이트가 공개되었다고 뜨네요. 지금 설치된 버전은 4.8.0.




3. Update 파일 다운로드


우선 OS 를 최신으로 update


$ sudo yum upgrade




저 위의 화면에 떠 있는 "Download" 를 누르면 될 것 같은데, 궂이 힘들게 해 봅니다.

Wowza 웹사이트에 가서, 회원 가입 > My Downloads 에서 4.8.5 버전 다운로드.



개인 PC 에 파일을 다운로드 받았으면, FTP 를 이용하든 해서 서버에 파일을 다운로드 받아 놓습니다.

저는 그냥 편하게 S3 사용 했습니다. (점점 AWS 로 대동단결)




4. 설치 파일 구성


먼저, 서비스를 내립니다.


$ sudo service WowzaStreamingEngine stop
$ sudo service WowzaStreamingEngineManager stop




Wowza 가 설치된 하위 directory 중에 updates 폴더 권한을 모두 읽을 수 있게 한 뒤, 다운로드 파일을 updates 에 모두 옮깁니다.


$ unzip WowzaStreamingEngine-Update-4.8.5.zip
$ sudo chmod -R 777 /usr/local/WowzaStreamingEngine-4.8.0/updates/
$ sudo mv * /usr/local/WowzaStreamingEngine-4.8.0/updates/




압축을 풀어서 updates 디렉토리에서 linux 용 명령어를 실행합니다.

최종적으로는 아래와 같은 depth 를 가지게 됩니다.


/usr/local/WowzaStreamingEngine-4.8.0/updates/WowzaStreamingEngine-4.8.5/linux



$ cd /usr/local/WowzaStreamingEngine-4.8.0/
$ cd updates/
$ cd WowzaStreamingEngine-4.8.5/linux/

$ pwd
/usr/local/WowzaStreamingEngine-4.8.0/updates/WowzaStreamingEngine-4.8.5/linux

$ sudo chmod +x *.sh
$ sudo ./update.sh 


오잉?!!!! Java 9 이상이 설치되어야 한다고 하네요. 기본으로 Java 8 이 깔려 있었습니다.



어쩔 수 있나요, Java 9 및 Java 13 도 깔아 줍니다. 자세한 설명은 아래 포스트를 참조해 주세요.


* Java | OpenJDK 업데이트 및 선택 변경

https://chocoball.tistory.com/entry/Java-OpenJDK-update-change




5. update.sh


Java 환경을 만들어 주면, 문제 없이 설치가 시작됩니다. sudo ./update.sh !!!



응 업데이트 하셈.



기존 설정은 backup 으로 옮기고 업데이트가 끝납니다. 요즘은 서버 성능이 좋은지라, 예전 보다 엄청 빨라졌네요.

(거의 10여년 전에 회사 최초로 linux 상에서 Wowza 깔아봤었슴)


다시, 서비스 올려 줍니다.


$ sudo systemctl daemon-reload
$ sudo service WowzaStreamingEngine start
$ sudo service WowzaStreamingEngineManager start






6. 4.8.5


Management UI 에서 버전 확인해 봅니다.



오늘도 알찬 하루였습니다.


FIN


'Cloud' 카테고리의 다른 글

AWS | Lightsail 과 Outline 이용하여 VPN 만들어 보기  (9) 2020.07.26
And

Software | Windows 10 Pro 와 Office 2019

|

이번에 새로 PC 를 맞추면서, 기존 Windows 10 USB 를 가지고 인스톨 하려니 되지 않았습니다.


Windows 10 의 USB 이미지는 극초기에 나온 사양인데, PC 는 최신 사양이라 뭔가 맞지 않았을 것 같습니다.

결국 Microsoft 웹페이지에서 최신 ISO 를 다운로드 받아 설치하였습니다. 아래 포스트에서 상황설명이 조금 더 되어 있습니다.


* Hardware | Intel NUC10i7FNK 구입기

https://chocoball.tistory.com/entry/Hardware-Intel-NUC10i7FNK-buy




1. Windows 10


Windows 10 을 새로 구입하려면 공홈에서 10만원 ~ 20만원대에 구입이 가능합니다.

어디선가, eBay 에서 5천원 정도로 KEY 를 판매한다는 글을 보게 됩니다.


궁금해 집니다. 저작권에 환장하는 Microsoft 인데, 그럴리가...



궁금하기도 하니, TEST 목적 으로 결제를 해 봅니다.



결제를 하니, 바로 email 로 Key 가 배달됩니다!!!



Windows 10 의 정품 인증 링크를 클릭하여, email 로 받은 Key 를 입력해 봅니다.



인증 서버와 통신하는 것 같습니다.



오잉!!!!!!!!!! @.@ 정품인증 성공!



사람들이 이야기 하는 상황이 현실이 되는 순간입니다. 저는 순수히 TEST 목적임을 밝힙니다.




2. Office 2019


OS 인, Windows 10 가 이렇다라고 한다면 Office 도 궁금해 지더군요.

마찬가지로 궁금하기도 하니, 순수히 TEST 목적 으로 결제를 해 봅니다.



저작권 수입을 중시하는 미국 사이트인 eBay 에서 검색하니 바로 뜹니다. 결제해 봅니다.



이번에는 몇 시간 이후에 메일이 도착했습니다. 처음에는 사기당한게 아닌가 했습니다.
역시 신용의 사회, 미쿡이군요...


Office 공홈에서 위의 항목을 클릭합니다.



email 로 받은 Key 를 입력하고, 국가 정보와 언어를 선택합니다.



오잉! 이것도 되는건가? 제품 키가 확인되었다고 나옵니다.

그런 다음, 설치 파일이 다운로드 됩니다.



설치 파일을 실행하여 Office 를 설치합니다.




3. Office 2019 의 activation


Office 2019 는 설치는 되었지만, 끝난 것이 아니였습니다. 실제로 PowerPoint 를 열었더니만, 아래와 같이 뜹니다.



아까 배달된 email 을 잘 살펴보니, 그 다음 step 이 설명되어 있었습니다.

유선 전화 확인으로 인증 형태를 변경하고, 아래 사이트에서 2단계에 나타나는 숫자들을 입력해 보라고 나옵니다.



Office 에서 떴던 번호들을 입력하고, 오른쪽 버튼을 누르니 한참동안 아이콘이 뱅글뱅글 돕니다.

그런 다음, 뭔가 새로운 숫자 배열이 나타났습니다.



3단계 입력 부분에 위에서 얻은 숫자들을 입력합니다.



Microsoft 를 이용해 주셔서 감사합니다라는 메시지를 받습니다.



사이트를 보니, 중국이 관련 프로세스와 웹사이트를 만든 것 같은데, Key gen. 에 대한 로직이 뚫린게 아닌가 합니다.




FIN


마지막으로 다시 말씀 드리지만, 저는 순수히 TEST 목적임을 밝힙니다.

창과 방패처럼 기술 발전은 꾸준하군요.


양자컴퓨터가 조금 있으면 나온다는 이야기를 하고 있는 시대이고,

수 많은 사람들이 컴퓨터 공학 전공 및 IT 산업에 종사하다 보니, 이제 이런 방식의 인증은 의미가 없어지는 듯 합니다.


상황을 Microsoft 도 인지하고 있을 터이니, 향후 OS 들은 다른 방식을 취하게 될 지도 모르겠습니다. 또 뚫리겠지만...

아님 Linux 처럼 되던가.


기술이란 무엇인가를 다시금 생각하게 하는 하루였습니다.


And

Software | AWS Certified 자격증 취득기 - 4

|

이 포스트는 AWS 인증 자격시험 네 번째인, AWS Certified Developer - Associate 취득기가 되겠습니다.


* Exam Name - AWS Certified Developer – Associate

* Exam Code - DVA-C01

* Online Class - Exam Readiness: AWS Certified Developer – Associate (Digital)


이 시험준비에 앞서 "Cloud Practitioner", "Solution Architect - Associate", 그리고 "Solution Architect - Professional" 도전기는 아래 포스트를 참고해 주세요.


* Software | AWS Certified 자격증 취득기 - 3

https://chocoball.tistory.com/entry/Software-AWS-Certified-3


* Software | AWS Certified 자격증 취득기 - 2

https://chocoball.tistory.com/entry/Software-AWS-Certified-2


* Software | AWS Certified 자격증 취득기 - 1

https://chocoball.tistory.com/entry/Software-AWS-Certified-1




1. 소개


Developer - Associate 시험은 개발 조직이 어떻게 AWS 시스템과 접목되며, 특히 CI/CD - 개발 코드 관리 및 배포를 부분을 봅니다.

자세한 내용은 아래 소개서를 참고해 보세요.


AWS_certified_developer_associate_blueprint.pdf

AWS Certified Developer-Associate_Exam Guide_v1.3_Final_KOREAN.pdf




2. AWS Training 사이트


Developer - Associate 는 아래와 같은 path 를 가집니다. Developer - Associate 의 상위는 DevOps - Professional 입니다.

당연히 DevOps - Professional 이 목표이긴 한데, 그 전에 Developer / SysOps 를 모두 취득하고 도전하려 합니다.

일단 Developer - Associate 부터 시작.


* Developer Learning Path

https://aws.amazon.com/training/path-developing/



항상 하던 것 처럼, 우선 AWS Training 사이트에서 제공해 주는 온라인 강의를 들었습니다.

PPT 로 내용을 정리하여, 공부하다 머리 아플 때 한번씩 읽어 봅니다. 쉬운 내용이라, 리프레쉬용으로 좋습니다.


* Exam Readiness: AWS Certified Developer – Associate (Digital)

https://www.aws.training/Details/Curriculum?id=19185

AWS_DVA-C01_20200511_chocoball.pptx




3. 공부 자료


공부는 약 한달간, 퇴근하고 잠깐, 그리고 주말 시간 날 때마다 했습니다.

집중해서 공부한 시간은, 약 50시간 정도 될까 싶습니다.


- 평일 : 3 시간 * 10 = 30 시간

- 주말 : 5 시간 * 4 = 20 시간


위의 PPT 외에 아라공 카페에서 알게된 분으로 부터 받은 덤프 및 인터넷에서 찾은 내용을 모두 모아 봤습니다.

누구라고 밝히지 못하나, 제공해주신 카페 회원님께 감사의 말씀을 여기에 남겨 놓습니다. 감사합니다!!!


DVA_C01_20200602.zip




4. 시험 등록


오랜만에 Pearson VUE 에서 시험보기로 합니다.



시험명은, "DVA-C01: AWS Certified Developer - Associate" 입니다.



지역 테스트 센터를 검색 합니다. 코로나19 로 인하여 잡을 수 있을까 궁금했습니다.



항상 그렇듯 시험 언어는 영어 입니다. 영어가 약하더라도 AWS 는 미국 솔루션이니, 영어로 공부하고 적응하는 것이 당연 좋습니다.



17만원. 작지 않은 금액입니다. 떨어지면 공중으로 훨훨. 아까워서라도 악착같이 공부하게 됩니다.



ESL 혜택을 신청해 놓은지라, 자동으로 30분 추가 혜택을 받는다는 내용 입니다.



여러 테스트 센터를 찾다가, 저와 인연이 깊은 "KD Tech 영등포 테스트 센터" 로 정했습니다.



날짜가 그리 널널한 것은 아니네요.



MS 시험때와는 다르게, 09:30 부터 시험 응시가 가능했습니다.

5월 22일에 신청 했지만, 회사 밤샘 업무로 인하여 체력이 버티질 못해, 결국 6월 2일에 보게 됩니다.



COVID-19 에 대한 주의사항이 추가되었습니다. 마스크 필수에 발열 체크 등에 관한 내용 들 입니다.



두둥!!! 결제.



최종 확인.



매번 이용해 주셔서 감사합니다 인사를 마지막으로 시험 등록은 마무리.



입금 완료 메일이 바로 날라 옵니다.



AWS Training 사이트에 가면 "Upcoming Exams" 에 일정이 잡혀 있음이 나타납니다.

매일 저 날짜만을 보며 쉬고싶은 욕구, 놀고싶은 욕구를 참아가면 공부합니다.





5. Practice 시험


본방 시험을 대비하여 연습 시험 - Practice - 시험을 봐 봅니다.



전 시험 합격을 통해 받은 Practice 바우처를 사용하여 무료로 시험 볼 수 있습니다.



Pearson VUE 를 이용해서 Practice 시험을 등록해 봅니다.



아래 화면까지 진행이 되고 난 후, "ESL+30" 혜택을 받는 사람들은 직접 통화해서 등록해야 한다네요.

Practice 시험의 장점이, 등록하고 바로 볼 수 있다는 것인데, 등록을 어렵게 해 놨습니다.



시험 등록에 시간을 사용하고 싶지 않으니, Pearson VUE 시험 등록을 포기하고 PSI 에서 등록합니다. 한방에 됩니다.



다만, 30분 추가 혜택은 없군요. 연습 시험은 문항 자체가 적어서 30분 혜택은 필요 없습니다.



Practice 시험 바우처를 입력하여, 2만 2천 8백원이 0 원으로 되는 마술.



온라인 시험이므로, 등록하자 마자 응시할 수 있습니다.



"Launch Exam" 을 통해서 시험 Go Go.



이 시험이 맞아? 라고 확인 후, "Start" 하면 바로 시작됩니다.



60분에 20문항이었습니다.



시험이 끝나고 바로 확인 메일이 옵니다. Overall Score 는 60%... 60점이라는 소리 입니다. 적어도 70% 는 되어야 합격라인 입니다.

이 결과를 통해 토할것 같이 공부에 박차를 가합니다.



이 Developer - Associate - Practice 시험 캡춰하고 정답 확인한 PPT 를 첨부합니다.


AWS_DVA-P01_20200601_chocoball.pptx




6. 본방 시험 당일


아침 5시에 일어나 샤워하고 5시 40분 버스를 타고 KD Tech - 영등포로 출발합니다.

지하철로 환승 하고 멍하니 앉아 있다가, 지하철 역 하나를 지나쳐 버렸습니다. 7시 30분 정도에 도착 예정이었으나 7시 50분 정도에 도착.



작년 MS 시험 볼 때는 1층에 말초밥집이였으나, 삼겹살집으로 바뀌었네요. 먹는 장사는 힘든 것 같습니다.



일전에는 없던 안내가 1층에 붙어 있네요.



한국국방인재연수원이라는데 군복 입은 사람을 한번도 본 적이 없습니다.



한시간 반 정도 시간이 있으니, 새로운 문제는 보지 않고, 풀었던 문제를 리뷰 합니다. 리뷰 할 때마다 새롭군요.

시험 전에는 항상 콜라 계열을 마셔, 뇌를 부스트 시켜 놓습니다.





7. 시험이 끝나고


역시나 머리를 극한까지 쥐어 짜는 지옥같은 시간이었습니다. 160분 시험 꽉 채워서 끝나고 나니, 오후 1시쯤이군요.

터벅터벅 지하철 쪽으로 걸어가다 베트남 쌀국수 집을 발견합니다. 괜찮아 보여 점심을 때우기로 합니다.



똠양꿍 쌀국수가 끌렸는데, 일단 기본 메뉴를 시킵니다. 주문은 "노상 프리미엄 쌀국수".



창문으로 보이는 좁은 골목이 흡사 베트남 느낌이 나는 듯.



맑은 국물과 충분한 면의 양이, 프리미엄이구나 합니다.



양평역 2번 출구 지하에 보이는 큰 대문. 평소에는 뻘쭘해서 가까이 못가고 사진만 찍었지만, 사람들이 별로 없으니, 가까이 다가가 봅니다.



차수문 이었군요. 홍수나 지상에 물이 차오르면 지하철로 물이 들어오는 것을 막는 장치인 듯 합니다.



실제로 한강 본류와 가까운 안양천 바로 옆에 역이 있으니, 차수문이 필요할 듯 합니다.

다만, 물이 콸콸 흘러들어 오는 상황이 발생하면, 저 메뉴얼에 따라 정확히 작동시킬 수 있는 시민이 얼마나 있을까 하는 궁금함이 듭니다.





8. 시험 결과


당일 저녁때 쯤 해서 결과가 올라 왔습니다.



PASS 의 문구는 언제나 짜릿합니다. 이 맛에 시험에 도전하는 것 같습니다. 720 점 커트라인에 748 점. 역시 PASS 는 턱걸이 입니다.

모르는 사람은 최소한의 노력으로 최대의 효과를 보는 방법이라 하지만, 사실 저는 최대한의 노력이었습니다. ㅠㅠ



인증서 PDF 도 다운로드 해 봅니다. 응 축하해, 너는 Developer - Associate 자격이 주어졌어.





FIN


Big Data - Specialty 자격 시험이 7월 1일부로 retired 된다고 합니다. 미친척 하고 한달도 안남았지만, 6월 30일자에 등록합니다.


And

Software | Bing webmaster tools 사용기

|

검색엔진에 블로그를 노출시키기 위해 여러 작업들을 해 왔습니다.


* Software | 블로그를 검색엔진에 노출시키기
    - https://chocoball.tistory.com/entry/Software-showing-blog-at-search-engine


이번에는 Microsoft 의 검색 엔진인 bing 에 노출시켜 보겠습니다.





1. 등록


MS 계정이 있으면 그대로 사용해도 되고, 새로 만들어도 됩니다. 요즘은 Facebook / Google 계정으로도 생성할 수 있습니다.



다른 webmaster tool 에서처럼 사이트를 등록하면서 시작합니다.



Google Search Console 을 통해 사이트 정보를 긁어오겠다고 합니다. 역시 구글 갓!



역시나 관련된 code 를 HTML 의 HEAD 에 삽입해줘야 합니다.

Bing 에서 발급한 XML 파일을 심어줘도 되는데, 파일 하이제킹이 가능할 수 있으니, meta code 형식으로 등록해 줍니다.



Bing 과 연결될 meta code 를 HTML HEAD 에 넣어 줍니다.



뿅! 연동 완료 되었습니다. 다만 시간차가 좀 있습니다. Bing 의 시스템은 빠릿빠릿 하지 않는 듯 해요. 조금 답답합니다.





2. Meta Tag


티스토리에는 이런 류의 Meta Tag 등록 플러그인이 있습니다.



등록 방법은, "블로그홈 관리 > 플러그인" 메뉴에서 선택할 수 있습니다.



 Meta Tag 플러그인을 활용하여 위의 스샷처럼 등록할 수도 있고, 유명한 태그들은 이미 플러그인이 준비되어 있는 것을 활용해도 됩니다.



구글 에널리틱 도 준비되어 있습니다.

다만 차이는, 준비된 플러그인을 통해서 만들어진 JavaScript 와 해당 업체에서 안내한 것과 조금 다릅니다.


아래는 플러그인에서 자동 생성되는 JavaScript.



아래는 Google 이 안내한 JavaScript 입니다.






개인적으로는 Google 이 안내한 JavaScript 가 깔끔하나, 온/오프로 사용이 간편한 플러그인이 관리 차원에서는 더 편합니다.

참고로, 네이버 애널리틱스 등록입니다.



플러그인에서 제공하는 NAVER Analytics 등록 JavaScript.





NAVER 가 안내한 JavaScript




안전을 위해 "encodeURI" 명령어를 중간에 넣어 줬네요. 프로세싱을 깎아먹지만, 오히려 이 방법이 더 세련된 듯 합니다.

요는 어느 쪽을 선택하든 동일하다는 것. 관리적인 측면을 보면 플러그인 방식을 추천.




3. Sitemap


가장 효과적인 Sitemap 등록 기능도 제공합니다.



가지고 있던 Sitemap 을 등록시켜 줍니다. 크롤링이 제대로 동작하지 않는 Bing 에서는 Sitemap 에 꽤나 의존하는 듯 합니다.

Sitemap XML 파일 생성과 활용법에 대해서는 이 글의 맨 처음에 소개된 아래 글에서 확인할 수 있습니다.


* Software | 블로그를 검색엔진에 노출시키기
    - https://chocoball.tistory.com/entry/Software-showing-blog-at-search-engine




4. 모니터링


등록 하고 일주일이 넘도록 제대로 동작하지 않았습니다. 그러다가 조금씩 조금씩 데이터가 쌓여 가더군요.



Bing 의 낮은 인지도 때문인가, 아니면 시스템이 세련되지 못해서 그런지는 잘 모르겠네요.

그치만 확실한건 아직 쓰레기 레벨이라는 것.




5. 기타 기능


결국 사이트를 분석해주는 툴이기 때문에, 요즘 트렌드에 맞게 모바일 기기 대응인지 확인하는 기능이 있습니다.



모바일 친화적으로 결과를 표시해 줍니다. 만, 제가 느끼기엔 저의 블로그는 전혀 모바일 친화적이 아닙니다.

그림 re-size 라든지, 글의 개행이 모바일에서 보면 개판인 것을 알고 있거든요. 적용 된 Skin 문제에서 기인한 부분도 있습니다만, 자세히 테스트를 못한다는 부분에서 별로 믿을만한 툴은 아닙니다.


SEO 대책을 위한 어드바이스도 해줍니다.



이 기능은 잘 되어 있습니다.



이렇게 평가한 이유는 잘 잡아내서 입니다.



og:sitename 등은 bot 들이 크롤링 함에 있어서 중요한 확인 항목입니다만, 티스토리는 이걸 자동 생성 해버립니다.

영어 사이트들에서 잘 검색되도록 영어로 노출되게 하고 싶으나, 블로그 이름을 그냥 박아 버립니다.



Markup Validator 는 HTML code 와 Meta tag 들이 잘 사용되어 있는지를 확인해 줍니다. 이 기능도 별로 입니다.

이유로는 한글을 제대로 인식하지 못합니다. UTF-8 을 표준으로 밀었던 Microsoft 아니였어? 라는 생각이 드는 대목.



Security 부분에서는 사이트에 내재된 Malware / Phishing 코드가 있는지 검사해 줍니다.


이건 마음에 듭니다.




6. Bot 블럭


크롤링 에러가 매우 많이 쌓입니다. 결국 크롤링을 못하고 있다는 이야기.



티스토리에서 Bing 관련 Bot 은 block 에 분류되어 있는게 아닌가 합니다. 아마도 WAF 에서 막는 설정이 되어 있는지도.

그만큼 Bing 은 인기가 없는 것이겠죠.



관리자에게 이야기 해서 Bot 이 정상 작동할 수 있도록 하라고 안내해 줍니다.




7. SEO Reports


이 Bing Webmaster Tool 의 사용의미인 "SEO Reports" 입니다.



역시 위에서 이야기한 og 관련된 description 문제가 가장 크다고 알려 줍니다.



티스토리가 개선되어 og:name / og:description 을 사용자가 직접 지정한 것이 유효하게 되면 SEO 대책은 끝날 것 같습니다.





FIN


Windows OS 처음 인스톨 하면, Internet Explorer 에서 기본 포털사이트로 보여주는 Bing.
그에 딸린 Webmaster Tool 이다 보니, 인지도가 없어서 티스토리에서 지원도 없고, Bot 이 WAF 단에서 걸리는 신세...
Beta 기능이라고 표시된 메뉴들은 언제 Beta 딱지를 땔지 나중에 확인해 보겠습니다.


And

Software | NAVER Analytics 사용기

|

블로그 방문자 및 웹사이트 전략 - SEO - 를 위해 Google Analytics 에 대해 알아 봤었습니다.


* Software | GAIQ - Google Analytics for Beginners
    - https://chocoball.tistory.com/entry/Software-GAIQ-Google-Analytics-for-Beginners

* Software | Google Analytics 를 이용한 블로그 분석
    - https://chocoball.tistory.com/entry/Software-Google-Analytics-blog

Google Analytics 를 통해 개선 사항이나, 접속 증가를 위해 몇 가지 튜닝도 해 봤었죠.


* Software | Daum AdFit 등록해 보기
    - https://chocoball.tistory.com/entry/Software-Daum-AdFit-apply


검색 사이트에서 노출을 높이기 위해서, 몇 가지 포털에 등록하기도 했습니다.


* Software | 블로그를 검색엔진에 노출시키기
    - https://chocoball.tistory.com/entry/Software-showing-blog-at-search-engine


블로그 활성화를 위해, 이번에는 NAVER Analytics 를 사용해 봤습니다.




1. NAVER Analytics



당연하게도 NAVER 계정이 있으면, 아래 사이트에 로그인 하면 됩니다.


* 네이버 애널리틱스

- https://analytics.naver.com/



NAVER 계정이 있으면 로그인 하면 되고, 없으면 만들면 됩니다.





2. 사이트 등록


이용 개시하면서, 약관에 동의 합니다.



그렇다고 합니다.



본격적으로 사용하려면, 모니터링 할 사이트가 필요합니다. 저는 제 블로그를 등록했습니다.



본인 소유의 확인을 위해, 그리고 사이트 분석을 위해, 등록시 발급 된 "등록 스크립트" 를 HEAD 부분에 넣어 줍니다.



등록 스크립트에는 사이트 ID 를 통해, 누구 소유의 사이트인지를 구분하고 분석해 줍니다.

결국 HTML 페이지의 HEAD 부분에 JavaScript + 사이트 ID 를 넣어주면 됩니다.






3. 요약 - 사이트 현황


정상적으로 사이트 ID 가 등록되고, 접속한 유저들의 브라우저가 심어놨던 JavaScript 를 통해 NAVER 서버에 정보를 보내기 시작하면, NAVER Analytics 에서 정보가 보이기 시작합니다.



사이트현황 에서는 정의한 기간 동안의 전반적인 접속 동향을 보여줍니다.



신규방문횟수, 재방문횟수, 평균 체류시간 등, 유용한 정보를 한눈에 볼 수 있다는 것이 장점입니다.



유입경로단말 정보, 그리고 유입검색어 정보도 보여줍니다.



TOP10 인기페이지 까지 보여줘서, 사이트현황 만으로 거의 모든 내용을 확인할 수 있어요.




4. 요약 - 대시보드


각 항목을 보면, "+ 대시보드추가" 가 있습니다. 의미하는 그대로, 원하는 항목에서 버튼 하나로 대시보드에 추가할 수 있어요.



저는 아래 항목들을 대시보드에 추가했습니다.



아래 보이는 것 처럼, 추가된 모든 그래프들이 대시보드에서 열람이 가능하다는 것을 알 수 있습니다.

참고로, 대시보드 상단의 "Check Points" 버튼을 클릭하면, 위의 메뉴가 뜨면서 넣고 빼기를 언제든 할 수 있습니다.



방문체류시간이 점점 늘어나는 것을 알 수 있구요.



TOP 방문지역 정보는 조금 이상하게 나오는 군요. NAVER 가 보유한 GeoIP 정보를 가지고 있는 IPDB 갱신이 필요해 보입니다.

다만, 행정구역 "구" 단위로 보여주는 것은 좋네요.



저의 블로그는 구글에서 가장 많이 검색되어 유입된다는 것을 알 수 있습니다. (글로벌 가자~)



당연 남초 사이트 이며, 35~39 연령대가 가장 많이 접속해 주시는 군요.



사람들 생활 패턴과 동일하게 "월요일" 이 가장 많이 방문하는 요일이고, 주말인 토/일에 낮은 방문률을 보여줍니다.





5. 방문분석


Visitor 분석 입니다. 대쉬보드에서 이미 확인할 수 있으나, 자세한 정보 열람이 가능합니다.



전일 대비 증감과 어떤 유형의 방문인지를 자세하게 알려줍니다.



페이지들의 열람 정보 입니다.



PV 가 UV 보다 살짝 높은 것을 보면, 방문해서 한페이지 정도만 보고 이탈하는 것 같습니다.

좀더 오랜동안 채류할 수 있도록 컨텐츠를 풍부하게 만들어야 겠네요. 인기 포스트들을 중심으로 연관된 글들에 집중해야 할 듯 합니다.

그치만, 취미로 하는 것이니 실제로는 신경쓰지 않을 껍니다.



시간대별로는 기상시 높아졌다가, 점심에 좀더 올라가고, 퇴근 전에 피크를 칩니다. 일하기 싫은 시간대에 인기있는 사이트... ㅠㅠ

퇴근시간대에도 한번 더 웨이브가 오네요. 이를 통하여 주요 방문자는 남자/30대 후반/직장인 이라는 것을 알 수 있습니다.



시간대별 방문 상세정보 입니다.



대시보드에서 봤던 정보 입니다.



요일별 방문분포의 자세한 내용 입니다.



방문체류시간은 처참하네요. 어떻게 1초를 못 넘기지? 접속 하자마자 바로 "아 아니구나..." 를 알 수 있다는 것인가?

어찌 되었든, 이 "방문체류시간" 을 늘리는 것이 광고 노출 최대의 결과가 됩니다.



방문경로깊이도 뼈아픈 정보 입니다. 대부분 접속한 글만 보고 이탈한다는 이야기 입니다.

하긴 저의 글들이 대중적이지는 않다는거 인정합니다.



미국이 가장 높게 나온건 이상합니다. 이참에 영어 사이트로 전환할까요?



영어 사용 언어권에 어필이 되면, 확실히 효과는 대단할 것 같습니다.





6. 유입분석


유입 현황 입니다. 검색을 통해서 노출된 링크를 타고 들어오는 사람이 대부분 입니다.



검색 사이트로는 구글을 통해서 제일 많이 들어왔네요.

한국어 블로그 이지만, 네이버 등 한국 포털을 통해서 들어오지 못하는 이유로는, 네이버가 자체 블로그 서비스를 가지고 있고, 블로그 노출에 대해 네이버 블로그들에 대해 우선순위를 높여놔서 그런게 아닌가 합니다.



이미 "네이버 웹마스터도구" 에도 등록되어 있음에도 불구하고, 이 현상은 NAVER 블로그를 더 노출하는 로직의 결과로 보입니다.


* Software | 블로그를 검색엔진에 노출시키기
    - https://chocoball.tistory.com/entry/Software-showing-blog-at-search-engine



각 항목을 클릭하면, 검색어도 표시해 줍니다. 이 기능은 좋아 보입니다. 2차원 정보를 같은 페이지에 보여주려는 노력의 결과인 듯.



유입검색어는 의지로 되는 것이 아닌 듯 합니다. 전혀 예상하지 못한 검색어가 인기 좋군요.



유입상세URL 은 당연 검색 사이트가 랭킹되어 있습니다.





7. 페이지분석


페이지들의 순위 입니다.


일전에 AWS 자격증 취득글이 가장 인기가 좋군요 :-)



시작 페이지와 종료 페이지는 동일합니다. 대부분 다른 글들은 보지 않고 떠났다는 이야기 이죠. ㅠㅠ



반송페이지의 의미는 들르지 마자, 그 페이지에서 바로 나갔다는 의미랍니다.





8. 실시간분석


말 그대로, 실시간 분석 입니다. 5초와 1분 단위로 접속자를 확인할 수 있습니다.


실시간 접속자 들의 인기 페이지 정보 입니다.





9. 사용자분석


뼈때리는 정보 입니다. 남초 사이트 인증!



성별 + 연령별 정보까지, 후벼 파 줍니다.



접속 단말의 정보. 이거야 User-Agent 분석의 결과.


각 OS 안에서 어떤 브라우저를 사용했는지도 보여 줍니다. 이런 2차원적인 표시 좋습니다.



웹브라우저 사용 비율 기준 + OS 정보를 표시해 줍니다.



아까는 OS > 웹브라우저 순서였고, 이 페이지는 그 반대인 웹브라우저 > OS 입니다.



CSS 디자이너에게는 필요한 화면해상도 정보도 알려줍니다.



해상도에 따른 OS 사용 비율도 보여줍니다.





FIN


Google Analytics 와는 다르게, 기본 한글 사용과 직관적인 구성으로 사이트 분석의 입문으로 추천합니다.

다만, 다차원적인 검색과 목표 설정하는 Campaign (Google 가지고 있슴) 등의 기능까지 활용하는 상위 레벨로는 맞지 않습니다.


분석용 JavaScript 들을 블로그에 집어 넣다보니, 페이지가 열리는 시간이 조금 무거워진 느낌은 나네요.

다만, 요즘 기기들과 인터넷 환경이 좋으므로 당분간 유지해 보려 합니다.


And

Hardware | ESP32 NTP Server 이용한 시간 맞추기

|

지금까지 ESP32 에 관한 글은 아래를 참고해 주세요.


* Hardware | ESP32 Deep sleep 알아보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Deep-sleep

* Hardware | ESP32 Cryptographic HW 가속 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Cryptographic-HW-acceleration

* Hardware | EPS32 PWM 기능 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-EPS32-PWM

* Hardware | ESP32 의 internal sensor 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-internal-sensors

* Hardware | ESP32 의 Dual core 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Dual-core

* Hardware | ESP32 스펙 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-spec-check

* Hardware | ESP32 간단 사용기
    - https://chocoball.tistory.com/entry/Hardware-simple-review-ESP32


이 글을 마지막으로 ESP32 에 대해 대략적인 내용은 얼추 확인해 본 것 같습니다.

이후에는 WiFi 이용한 활용시에는 가능한 ESP32 를 사용해 보려 합니다.




1. NTP


본 포스트는 아래 글을 참조 하였습니다.


* Getting Date & Time From NTP Server With ESP32

- https://lastminuteengineers.com/esp32-ntp-server-date-time-tutorial/



NTP 서버란 인터넷에서 시간을 동기화 시켜주는 서버를 말합니다.
인증, GPS 위치와 연관된 시간 정보, 동기화와 관련된 timestamp 등, 인터넷 서비스의 거의 모든 기능들이 동일한 "시간" 정보가 필요합니다.


동일한 시간 기준으로 동작해야 하는 서비스를 위해, 인터넷에서는 NTP 라는 서비스가 지원되고 있습니다.


* Network Time Protocol

- https://en.wikipedia.org/wiki/Network_Time_Protocol


이를태면, 정확한 시간 정보를 가져올 수 있는 서버들이 존재한다는 것이죠.




2. WiFi



"인터넷" 을 통해 시간 정보를 가져와야 하므로, WiFi 등의 인터넷 연결이 필수 입니다.

ESP32 는, WiFi 연결을 위해 "WiFi.h" 라이브러리를 지원합니다. 이를 통해 쉽게 WiFi 연결을 실현해 줍니다.

지금까지 Arduino + ESP8266 에서는 AT command 를 이용하여, 하나하나 명령어를 정의해야 했었는데, 그럴 수고를 덜어줍니다.


const char* ssid       = "YOUR_SSID";
const char* password   = "YOUR_PASS";


인터넷 접속을 위한 WiFI SSID 및 비번 정의를 하면 끝 입니다. 정말로 이걸로 끝입니다.




3. NTP


NTP 서버를 통해 시간을 가져오는 소스는 다음과 같습니다.


#include "WiFi.h"
#include "time.h"

const char* ssid       = "YOUR_SSID";
const char* password   = "YOUR_PASS";

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;

void printLocalTime() {
	struct tm timeinfo;
	if(!getLocalTime(&timeinfo)) {
		Serial.println("Failed to obtain time");
		return;
	}
	Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

void setup() {
	Serial.begin(115200);
	
	// connect to WiFi
	Serial.printf("Connecting to %s ", ssid);
	WiFi.begin(ssid, password);
	while (WiFi.status() != WL_CONNECTED) {
		delay(500);
		Serial.print(".");
	}
	Serial.println(" CONNECTED");
	
	// init and get the time
	configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
	printLocalTime();
	
	// disconnect WiFi as it's no longer needed
	WiFi.disconnect(true);
	WiFi.mode(WIFI_OFF);
}

void loop() {
	delay(1000);
	printLocalTime();
}


위의 소스를 각 로컬 상황에 맞게 설정해줘야 합니다.


const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;


우선, NTP 서버는 "pool.ntp.org" 로 정의 합니다. 이 FQDN 을 통해 NTP 서버를 할당 받습니다.


"gmOffset_sec" 는 GMT 기준으로 얼마나 차이나는지를 확인합니다.

한국은 그리니치 천문대 기준 9시간 추가된 시간대인, "GMT+9" 이므로 "3600 * 9 = 32400" 만큼 더해주면 됩니다.


또한, "daylightOffset_sec" 은, 서머타임 적용 지역이면, 한시간인 3600 을 적용하면 됩니다.

우리나라는 서머타임 적용은 80년대에 일시적으로 적용하고, 그 이후 사용되지 않으므로 "0" 으로 정의합니다. (옛날 사람...)


위의 내용을 적용하고 실행하면 다음과 같이 됩니다.



한국 상황에 맞게, 요일까지 정확히 표시할 수 있는 것을 확인했습니다.



FIN

ESP32 의 WiFi 구현이 얼마나 간단한지를 확인해 보기 위해 NTP 서비스를 활용해 봤습니다.
앞으로는 ESP32 를 통하여 다양한 project 를 해봐야 겠네요.

끝.


And

Hardware | ESP32 Deep sleep 알아보기

|

ESP32 는 WiFi 및 Bluetooth 에 추가하여 Dual-core CPU 에 sensor 등, 작은 사이즈에 많은 기능을 내포하고 있습니다.

본격적인 IoT 생활을 위해 Arduino 보드에서 ESP32 로 넘어가는 중이라 ESP32 에 대해 공부하고 있습니다.


지금까지 작성된 ESP32 에 관한 글들은 아래 포스트들을 참고해 주세요.


* Hardware | ESP32 Cryptographic HW 가속 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Cryptographic-HW-acceleration

* Hardware | EPS32 PWM 기능 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-EPS32-PWM

* Hardware | ESP32 의 internal sensor 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-internal-sensors

* Hardware | ESP32 의 Dual core 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Dual-core

* Hardware | ESP32 스펙 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-spec-check

* Hardware | ESP32 간단 사용기
    - https://chocoball.tistory.com/entry/Hardware-simple-review-ESP32



1. Power Modes


ESP32 는 사용 전력량을 알맞게 활용할 수 있도록 5가지 Power 모드를 제공하고 있습니다. Off-Grid 에서의 활용에서는 필수겠죠.



아래 테이블은, 각 mode 들에 따른 ESP32 부위별 active / inactive 와 사용 전력 정보 입니다.


* Insight Into ESP32 Sleep Modes & Their Power Consumption
    - https://lastminuteengineers.com/esp32-sleep-modes-power-consumption/


--------------------------------------------------------------------------------
| Power Mode  | Active                 | Inactive               | Power        |
|             |                        |                        | Consumption  |
|------------------------------------------------------------------------------|
| Active      | WiFi, Bluetooth, Radio |                        | 160 ~ 260 mA |
|             | ESP32 Core             |                        |              |
|             | ULP Co-processor       |                        |              |
|             | Peripherals, RTC       |                        |              |
|------------------------------------------------------------------------------|
| Modem Sleep | ESP32 Core             | WiFi, Bluetooth, Radio |   3 ~ 20 mA  |
|             | ULP Co-processor, RTC  | Peripherals            |              |
|------------------------------------------------------------------------------|
| Light Sleep | ULP Co-processor, RTC  | WiFi, Bluetooth, Radio |     0.8 mA   |
|             | ESP32 Core (Paused)    | Peripherals            |              |
|------------------------------------------------------------------------------|
| Deep Sleep  | ULP Co-processor, RTC  | WiFi, Bluetooth, Radio |     10 uA    |
|             |                        | ESP32 Core, Peripherals|              |
|------------------------------------------------------------------------------|
| Hibernation | RTC                    | ESP32 Core             |     2.5 uA   |
|             |                        | ULP Co-processor       |              |
|             |                        | WiFi, Bluetooth, Radio |              |
|             |                        | Peripherals            |              |
--------------------------------------------------------------------------------


사용하지 않는 부분을 죽이고 최대한 사용 전력을 아끼는 방법입니다.

사양서에는, 좀더 자세한 power mode 별 소비 전력이 안내되어 있습니다.



이번 포스트에서 집중적으로 확인해 볼 Deep sleep 에서는 CPU 를 사용하지 않고, 소전력으로 돌아가는 ULP processor 를 활용합니다.



참고고, ESP32 에서 사용되는 전력의 많은 부분은 역시 WiFi/Bluetooth 이군요.





2. RTC_IO / Touch


Deep sleep 시에 ESP32 를 깨우거나 입력을 받아들이는 pin 은 RTC_IO / Touch 핀들 입니다.

즉, 이 pin 들을 통하여 ULP co-processor 에 자극을 줘서 deep sleep 에서 깨어날 수 있도록 open 된 핀들이라고 할 수 있겠네요.

참고로 모든 Touch 핀들은 RTC_IO 핀들에 포함되어 있습니다.





3. 깨우기 - timer


마침 Examples 에 정갈하게 소스가 올라와 있으니, 이걸 이용해서 확인해 봅니다.

File > Examples > ESP32 > DeepSleep > TimerWakeup


원본 소스는 다음과 같습니다. 5초마다 깼다가 바로 잠드는 시퀀스로 짜여져 있습니다.

wakeup_reason 을 통해, timer 외에 touch 나 external pin 에 의한 확인도 가능하게 만들어져 있네요.


/*
Simple Deep Sleep with Timer Wake Up
=====================================
ESP32 offers a deep sleep mode for effective power
saving as power is an important factor for IoT
applications. In this mode CPUs, most of the RAM,
and all the digital peripherals which are clocked
from APB_CLK are powered off. The only parts of
the chip which can still be powered on are:
RTC controller, RTC peripherals ,and RTC memories

This code displays the most basic deep sleep with
a timer to wake it up and how to store data in
RTC memory to use it over reboots

This code is under Public Domain License.

Author:
Pranav Cherukupalli - cherukupallip@gmail.com
*/

#define uS_TO_S_FACTOR 1000000ULL  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  5        /* Time ESP32 will go to sleep (in seconds) */

RTC_DATA_ATTR int bootCount = 0;

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32
  print_wakeup_reason();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up every 5 seconds
  */
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
  " Seconds");

  /*
  Next we decide what all peripherals to shut down/keep on
  By default, ESP32 will automatically power down the peripherals
  not needed by the wakeup source, but if you want to be a poweruser
  this is for you. Read in detail at the API docs
  http://esp-idf.readthedocs.io/en/latest/api-reference/system/deep_sleep.html
  Left the line commented as an example of how to configure peripherals.
  The line below turns off all RTC peripherals in deep sleep.
  */
  //esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
  //Serial.println("Configured all RTC Peripherals to be powered down in sleep");

  /*
  Now that we have setup a wake cause and if needed setup the
  peripherals state in deep sleep, we can now start going to
  deep sleep.
  In the case that no wake up sources were provided but deep
  sleep was started, it will sleep forever unless hardware
  reset occurs.
  */
  Serial.println("Going to sleep now");
  Serial.flush(); 
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This is not going to be called
}


Serial Monitor 를 통해, 5초마다 깨어나는 상황을 확인 할 수 있습니다.





4. 깨우기 - touch pin


터치센서를 통하여 잠에서 깨우는 소스 입니다. 이것도 마찬가지로 기본 제공되는 Example 을 이용하여 확인해 봤습니다.


File > Examples > ESP32 > DeepSleep > TouchWakeup

/*
Deep Sleep with Touch Wake Up
=====================================
This code displays how to use deep sleep with
a touch as a wake up source and how to store data in
RTC memory to use it over reboots

This code is under Public Domain License.

Author:
Pranav Cherukupalli - cherukupallip@gmail.com
*/

#define Threshold 40 /* Greater the value, more the sensitivity */

RTC_DATA_ATTR int bootCount = 0;
touch_pad_t touchPin;
/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

/*
Method to print the touchpad by which ESP32
has been awaken from sleep
*/
void print_wakeup_touchpad(){
  touchPin = esp_sleep_get_touchpad_wakeup_status();

  switch(touchPin)
  {
    case 0  : Serial.println("Touch detected on GPIO 4"); break;
    case 1  : Serial.println("Touch detected on GPIO 0"); break;
    case 2  : Serial.println("Touch detected on GPIO 2"); break;
    case 3  : Serial.println("Touch detected on GPIO 15"); break;
    case 4  : Serial.println("Touch detected on GPIO 13"); break;
    case 5  : Serial.println("Touch detected on GPIO 12"); break;
    case 6  : Serial.println("Touch detected on GPIO 14"); break;
    case 7  : Serial.println("Touch detected on GPIO 27"); break;
    case 8  : Serial.println("Touch detected on GPIO 33"); break;
    case 9  : Serial.println("Touch detected on GPIO 32"); break;
    default : Serial.println("Wakeup not by touchpad"); break;
  }
}

void callback(){
  //placeholder callback function
}

void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32 and touchpad too
  print_wakeup_reason();
  print_wakeup_touchpad();

  //Setup interrupt on Touch Pad 3 (GPIO15)
  touchAttachInterrupt(T3, callback, Threshold);

  //Configure Touchpad as wakeup source
  esp_sleep_enable_touchpad_wakeup();

  //Go to sleep now
  Serial.println("Going to sleep now");
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This will never be reached
}


GPIO15 번을 손으로 터치하면 깨어납니다.



Serial Monitor 에서도 touch pin 에서의 감지를 알려 줍니다.





5. 깨우기 - EXT(0) external wake ups


Pin 의 HIGH/LOW 입력을 통하여 깨우는 방법 입니다.


File > Examples > ESP32 > DeepSleep > ExternalWakeup


/*
Deep Sleep with External Wake Up
=====================================
This code displays how to use deep sleep with
an external trigger as a wake up source and how
to store data in RTC memory to use it over reboots

This code is under Public Domain License.

Hardware Connections
======================
Push Button to GPIO 33 pulled down with a 10K Ohm
resistor

NOTE:
======
Only RTC IO can be used as a source for external wake
source. They are pins: 0,2,4,12-15,25-27,32-39.

Author:
Pranav Cherukupalli -cherukupallip@gmail.com
*/

//#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex
#define BUTTON_PIN_BITMASK 0x16 // 2^4 in hex

RTC_DATA_ATTR int bootCount = 0;

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32
  print_wakeup_reason();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up for an external trigger.
  There are two types for ESP32, ext0 and ext1 .
  ext0 uses RTC_IO to wakeup thus requires RTC peripherals
  to be on while ext1 uses RTC Controller so doesnt need
  peripherals to be powered on.
  Note that using internal pullups/pulldowns also requires
  RTC peripherals to be turned on.
  */
//  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,1); //1 = High, 0 = Low
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_4,1); //1 = High, 0 = Low

  //If you were to use ext1, you would use it like
  //esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);

  //Go to sleep now
  Serial.println("Going to sleep now");
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This is not going to be called
}


원본 소스는 GPIO_33 번을 활용하게 되어 있으나, 핀 배열상 GPIO_4 로 바꾸도록 수정 해 봤습니다.

Linux 의 파일 시스템에서, 쓰기/읽기 정의에 사용되는 bit mask 방법을 사용하는 군요.


2^(pin 번호) 를 16진수로 표현하여 정의합니다. GPIO_4 이므로, 우선 2 의 4승 계산은 다음과 같습니다.


2^4 = 16



위의 결과를 16진수로 변경해야 합니다. 아래 사이트의 converter 를 이용하면 편합니다.


* Decimal to Hexadecimal converter
    - https://www.rapidtables.com/convert/number/decimal-to-hex.html



최종적으로 2^4 = 16 > 10 (Hexadecimal) 가 됩니다.


...

//#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex
#define BUTTON_PIN_BITMASK 0x10 // 2^4 in hex

...

//  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,1); //1 = High, 0 = Low
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_4,1); //1 = High, 0 = Low

...


BITMASK 값과 ext0GPIO_NUM_4 로 바꾸어 주면 정의가 완료 됩니다.
회로를 아래처럼 꾸며, 스위치를 누르면 깨어나는 방법입니다.


실제 사진은 다음과 같습니다.



정상 작동 되는군요.





6. 깨우기 - EXT(1) external wake ups


외부 입력을 통한 방법은 위의 EXT(0) 와 같으나, 이번에는 두 개의 스위치를 이용하는 방법 입니다.


/*
Deep Sleep with External Wake Up
=====================================
This code displays how to use deep sleep with
an external trigger as a wake up source and how
to store data in RTC memory to use it over reboots
 
This code is under Public Domain License.
 
Hardware Connections
======================
Push Button to GPIO 33 pulled down with a 10K Ohm
resistor
 
NOTE:
======
Only RTC IO can be used as a source for external wake
source. They are pins: 0,2,4,12-15,25-27,32-39.
 
Author:
Pranav Cherukupalli - cherukupallip@gmail.com
*/
 
#define BUTTON_PIN_BITMASK 0x8004 // GPIOs 2 and 15
 
RTC_DATA_ATTR int bootCount = 0;
 
/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;
 
  wakeup_reason = esp_sleep_get_wakeup_cause();
 
  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}
 
/*
Method to print the GPIO that triggered the wakeup
*/
void print_GPIO_wake_up(){
  int GPIO_reason = esp_sleep_get_ext1_wakeup_status();
  Serial.print("GPIO that triggered the wake up: GPIO ");
  Serial.println((log(GPIO_reason))/log(2), 0);
}
   
void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor
 
  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));
 
  //Print the wakeup reason for ESP32
  print_wakeup_reason();
 
  //Print the GPIO used to wake up
  print_GPIO_wake_up();
 
  /*
  First we configure the wake up source
  We set our ESP32 to wake up for an external trigger.
  There are two types for ESP32, ext0 and ext1 .
  ext0 uses RTC_IO to wakeup thus requires RTC peripherals
  to be on while ext1 uses RTC Controller so doesnt need
  peripherals to be powered on.
  Note that using internal pullups/pulldowns also requires
  RTC peripherals to be turned on.
  */
  //esp_deep_sleep_enable_ext0_wakeup(GPIO_NUM_15,1); //1 = High, 0 = Low
 
  //If you were to use ext1, you would use it like
  esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);
 
  //Go to sleep now
  Serial.println("Going to sleep now");
  delay(1000);
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}
 
void loop(){
  //This is not going to be called
}


여기서의 포인트는, 입력을 받는 복수의 GPIO 번호를 더해서 BITMASK 를 구하는 것 입니다.

사용된 GPIO 정보는 2번과 15번 입니다.


GPIO_2 + GPIO_15 > 2^2 + 2^15 = 32772



32772 의 16진수는 8004 입니다.



원본 소스에서 아래처럼 GPIO 의 BITMASK 변경과, 어떤 GPIO 가 눌렀는지의 표시, 그리고 EXT1 을 정의해 줍니다.


...

#define BUTTON_PIN_BITMASK 0x8004 // GPIOs 2 and 15
...

/*
Method to print the GPIO that triggered the wakeup
*/
void print_GPIO_wake_up(){
  int GPIO_reason = esp_sleep_get_ext1_wakeup_status();
  Serial.print("GPIO that triggered the wake up: GPIO ");
  Serial.println((log(GPIO_reason))/log(2), 0);
}
  
...

  //If you were to use ext1, you would use it like
  esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);

...


회로는 다음과 같이 스위치를 연결 했습니다. EXT0 와 다른 것은 복수 (두 개) 의 스위치를 입력받게 하는 것 입니다.



Serial Monitor 의 결과는 다음과 같아요. 어느 GPIO 핀에서 입력 받았는지를 표시해 줍니다.





7. 전류 확인 - Deep sleep


실재로 전류 변화가 있는지 확인해 봤습니다.



음... 그리 많이 차이나지 않군요.

Examples 에서 제공되는 기본 소스는 Wake up 만 확인하는 소스이지, 계산을 시키거나 하는 것이 아니라서 그런 것 같습니다.





FIN


배터리를 가지고 동작하는 장비들은 필수로 가지고 있어야 할 Power mode 들, 특히 Deep sleep 에 대해 알아 봤습니다.

전력 소비가 가장 심한 WiFi/Bluetooth 부분을 어떻게 활용하면서 운용해야 하는지를 많이 고민해야 할 것 같네요.


- WiFi/Bluetooth 연결 정보는 연결 실패 exception 이나 스케줄에 따라 실시

- 가능한 정보는 memory 에 저장하여 꺼내 쓰는 방식으로

- 배터리 방전 threshold 값을 모니터링 하고, 일정 값 이하로 내려가면 지속적인 alert 발생

- WiFi/Bluetooth 에 사용되는 전류량을 컨트롤 하여, 근거리 통신 -> 중거리 -> 장거리 통신으로 연결하게끔 구성

- DTIM (Delivery Traffic Indication Message) beacon mechanism 등을 활용

- 등등...



And

Hardware | ESP32 Cryptographic HW 가속 확인해 보기

|

ESP32 에 관한 글들은 아래 링크들을 참고해 주세요.


* Hardware | EPS32 PWM 기능 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-EPS32-PWM

* Hardware | ESP32 의 internal sensor 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-internal-sensors

* Hardware | ESP32 의 Dual core 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Dual-core

* Hardware | ESP32 스펙 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-spec-check

* Hardware | ESP32 간단 사용기
    - https://chocoball.tistory.com/entry/Hardware-simple-review-ESP32



1. Cryptographic Hardware Acceleration


한 13여년 전에 웹 서비스 구축 시, HTTPS (SSL) 처리에 CPU 연산을 너무 많이 사용해서 골치가 아팠던 경험이 있습니다.

당시에는 NIC 에 붙어있는 Intel 칩에서 SSL 가속 처리를 못해줘, OS 에서 처리하다 보니 CPU 들이 죽어 나갔죠.


막 HW 가속기 (PCI daughter card 형식) 들이 등장하기도 했습니다만, 어디까지나 실험적인 제품들이었고, OS 와 HW 특성을 많이 타다 보니 PoC 단계에서도 그닥 실효를 거두지 못했었습니다.


암호 연산에 대해서는 요즘 NIC 나 CPU 자체적으로 전용 명령어 set을 가지고 지원하는 시대이다 보니, 예전같은 걱정은 말끔히 사라졌네요.


근래에 출시된 ESP32 에도, 이 암호 연산용 HW 가속 기능이 내장되어 있습니다!

다이어그램 상, SHA / RSA / AES / RNG 등이 있네요.



사양서에도 이 HW Accelerator 에 대한 안내가 되어 있습니다.



Cryptographic hardware acceleration

- AES, SHA-2, RSA, elliptic curve cryptography (ECC), random number generator (RNG)


이번 글은 위의 HW Accelerator 의 몇 가지 기능 중, ESP32 의 hardware AES 에 대해 알아보고자 합니다.




2. AES


미국 정부가 1990년 후반까지 사용하고 있던 DES 암호화 기법이, 약 30대 정도의 PC 를 가지고 뚫리면서, 새로운 암호화 기법을 찾게 됩니다. 공모 결과 AES 가 채택되면서 유명해진 암호화 기법이에요.


AES 는 "Advanced Encryption Standard" 의 약자로 cryptographic symmetric cipher algorithm 을 기반으로 encryption 과 decryption 양쪽에 사용될 수 있는 장점을 가지고 있습니다.

참고로 아래 두 가지의 parameter 를 필요로 합니다.


IV (Initial Vector)

맨 처음 block 을 XOR 처리를 할 때, 덮어 씌우는 data block 이 존재하지 않습니다. 이를 보충해 주기 위한 인위적인 블럭이 IV 입니다.


Encryption Key

암호화 / 복호화에 사용되는 고유의 키 입니다.



너무 자세한 설명에 들어가면, 저의 지식이 바닦 치는 것이 보이기에 여기서 그만 합니다.

인터넷에 관련된 문서 및 동영상들이 어마어마 하니, 자세히 공부해 보고 싶으신 분을 넓은 인터넷의 세계로...




3. Software AES - ESP32


HW 가속을 시험해 보기에 앞서, AES 를 소프트웨어적으루 구현해본 분이 계셔서 따라 해봤습니다.


* AES Encryption/Decryption using Arduino Uno
    - https://www.arduinolab.net/aes-encryptiondecryption-using-arduino-uno/


우선 필요한 것은, Spaniakos 라는 분이 만드신 AES 라이브러리를 설치해 줍니다. 아래 Github 에서 라이브러리를 다운 받습니다.


* AES for microcontrollers (Arduino & Raspberry pi)
    - https://github.com/spaniakos/AES



그리고, Arduino libraries 폴더에 심어 놓으면 됩니다.



기본 준비가 되었으니, ESP32 에서 AES-CBC 방식의 암호화/복호화를 실행 해봅니다.


/*------------------------------------------------------------------------------ 
Program:      aesEncDec 
 
Description:  Basic setup to test AES CBC encryption/decryption using different 
              key lengths.
 
Hardware:     Arduino Uno R3 
 
Software:     Developed using Arduino 1.8.2 IDE
 
Libraries:    
              - AES Encryption Library for Arduino and Raspberry Pi: 
                https://spaniakos.github.io/AES/index.html
 
References: 
              - Advanced Encryption Standard by Example: 
              http://www.adamberent.com/wp-content/uploads/2019/02/AESbyExample.pdf
              - AES Class Reference: https://spaniakos.github.io/AES/classAES.html
 
Date:         July 9, 2017
 
Author:       G. Gainaru, https://www.arduinolab.net
              (based on AES library documentation and examples)
------------------------------------------------------------------------------*/
#include "AES.h"

AES aes ;

unsigned int keyLength [3] = {128, 192, 256}; // key length: 128b, 192b or 256b

byte *key = (unsigned char*)"01234567890123456789012345678901"; // encryption key
byte plain[] = "https://chocoball.tistory.com/entry/Hardware-ESP32-Cryptographic-hardware-acceleration"; // plaintext to encrypt

unsigned long long int myIv = 36753562; // CBC initialization vector; real iv = iv x2 ex: 01234567 = 0123456701234567

void setup () {
	Serial.begin(115200);
}

void loop () {
	for (int i=0; i < 3; i++) {
		Serial.print("- key length [b]: ");
		Serial.println(keyLength [i]);
		aesTest (keyLength[i]);
		delay(2000);
	}
}

void aesTest (int bits) {
	aes.iv_inc();
	
	byte iv [N_BLOCK];
	int plainPaddedLength = sizeof(plain) + (N_BLOCK - ((sizeof(plain)-1) % 16)); // length of padded plaintext [B]
	byte cipher [plainPaddedLength]; // ciphertext (encrypted plaintext)
	byte check [plainPaddedLength]; // decrypted plaintext
	
	aes.set_IV(myIv);
	aes.get_IV(iv);
	
	Serial.print("- encryption time [us]: ");
	unsigned long ms = micros ();
	aes.do_aes_encrypt(plain, sizeof(plain), cipher, key, bits, iv);
	Serial.println(micros() - ms);
	
	aes.set_IV(myIv);
	aes.get_IV(iv);
	
	Serial.print("- decryption time [us]: ");
	ms = micros ();
	aes.do_aes_decrypt(cipher,aes.get_size(),check,key,bits,iv); 
	Serial.println(micros() - ms);
	
	Serial.print("- plain:   ");
	aes.printArray(plain,(bool)true); //print plain with no padding
	
	Serial.print("- cipher:  ");
	aes.printArray(cipher,(bool)false); //print cipher with padding
	
	Serial.print("- check:   ");
	aes.printArray(check,(bool)true); //print decrypted plain with no padding
	
	Serial.print("- iv:      ");
	aes.printArray(iv,16); //print iv
	printf("\n-----------------------------------------------------------------------------------\n");
}


암호화를 걸 평문은, 이 포스트의 URL 을 사용했습니다. :-)



암호화/복호화 잘 됩니다. 속도도 좋네요.




4. Software AES - ATmega328


비교 대상으로 궁금하여, ATmega328 을 탑재한 Arduino nano 로 동일한 계산을 시켜보기로 합니다.

다만, "AES.h" 라이브러리를 include 한다고 제대로 실행되진 않는군요.


	aes.printArray(plain,(bool)true); //print plain with no padding


이유는, ATmega328 의 라이브러리에는 위의 printArray 에서 사용하는 printf_P 함수가 없기 때문입니다. (AES.cpp 에서 정의됨)

ESP32 의 FreeRTOS 에는 C 라이브러리 기본 탑재로 문제 없이 동작하지만, Arduino nano 에서는 동작하지 않습니다.


그리하여, 이를 대신할 function 을 만들어 봤는데, 징그럽게도 동작하지 않더군요.

수많은 삽질을 통해, 배열을 다른 함수의 인자로 전달하려면 배열의 pointer 와 그 배열의 크기를 명시해야 하는 것을 알게 되었습니다.

결국 아래처럼 변경하여 Arduino nano 에서도 동작을 성공 시켰습니다.


...

	showArray(iv, array_size_iv, 1);

...

void showArray (byte *result, int array_length, int hex_conv) {
	for (int i=0; i < array_length; i++) {
		if (hex_conv) {
			Serial.print(result[i], HEX);
		} else {
			Serial.print((char)result[i]);
		}
	}
	Serial.println();
}


최종 소스는 다음과 같습니다.


#include "AES.h"

AES aes ;

unsigned int keyLength [3] = {128, 192, 256}; // key length: 128b, 192b or 256b

byte *key = (unsigned char*)"01234567890123456789012345678901"; // encryption key
byte plain[] = "https://chocoball.tistory.com/entry/Hardware-ESP32-Cryptographic-hardware-acceleration"; // plaintext to encrypt

unsigned long long int myIv = 36753562; // CBC initialization vector; real iv = iv x2 ex: 01234567 = 0123456701234567

void setup () {
	Serial.begin(115200);
}

void loop () {
	for (int i=0; i < 3; i++) {
		Serial.print("- key length [b]: ");
		Serial.println(keyLength [i]);
		aesTest (keyLength[i]);
		delay(2000);
	}
}

void aesTest (int bits) {
	aes.iv_inc();
	
	byte iv [N_BLOCK];
	int plainPaddedLength = sizeof(plain) + (N_BLOCK - ((sizeof(plain)-1) % 16)); // length of padded plaintext [B]
	byte cipher [plainPaddedLength]; // ciphertext (encrypted plaintext)
	byte check [plainPaddedLength]; // decrypted plaintext
	
	aes.set_IV(myIv);
	aes.get_IV(iv);
	
	Serial.print("- encryption time [us]: ");
	unsigned long ms = micros ();
	aes.do_aes_encrypt(plain, sizeof(plain), cipher, key, bits, iv);
	Serial.println(micros() - ms);
	
	aes.set_IV(myIv);
	aes.get_IV(iv);
	
	Serial.print("- decryption time [us]: ");
	ms = micros ();
	aes.do_aes_decrypt(cipher,aes.get_size(),check,key,bits,iv);
	Serial.println(micros() - ms);
	
	Serial.print("- plain:   ");
	//aes.printArray(plain,(bool)true); //print plain with no padding
	int array_size_p = sizeof(plain);
	showArray(plain, array_size_p, 0);
	
	Serial.print("- cipher:  ");
	//aes.printArray(cipher,(bool)false); //print cipher with padding
	int array_size_ci = sizeof(cipher);
	showArray(cipher, array_size_ci, 0);
	
	Serial.print("- check:   ");
	//aes.printArray(check,(bool)true); //print decrypted plain with no padding
	int array_size_ch = sizeof(check);
	showArray(check, array_size_ch, 0);
	
	Serial.print("- iv:      ");
	//aes.printArray(iv,16); //print iv
	int array_size_iv = sizeof(iv);
	showArray(iv, array_size_iv, 1);
	Serial.println("-----------------------------------------------------------------------------------");
}

void showArray (byte *result, int array_length, int hex_conv) {
	for (int i=0; i < array_length; i++) {
		if (hex_conv) {
			Serial.print(result[i], HEX);
		} else {
			Serial.print((char)result[i]);
		}
	}
	Serial.println();
}


아래는 Arduino nano 에서 실행시킨 결과 입니다.

ESP32 에서 Software 로 돌린 AES 결과와 비교시, 걸린 시간 빼곤 완벽히 동일합니다.



ESP32 vs. ATmega328 의 CPU 차에 의한 software AES 계산은 encryption = 27 배, decryption = 20 배 정도 차이 났습니다.


----------------------------------------------
| bits | ESP32 | ATmega328 | diff. (multiply)|
|--------------------------------------------|
| 128  |  159  |   4396    |       27.6      |
|      |  267  |   5388    |       20.1      |
|--------------------------------------------|
| 192  |  189  |   5156    |       27.2      | 
|      |  321  |   6392    |       19.9      |
|--------------------------------------------|
| 256  |  220  |   5964    |       27.1      |
|      |  376  |   7432    |       19.7      |
----------------------------------------------


ESP32 를 찬양하라!





5. Hardware AES - library


마지막으로 ESP32 의 HW AES 를 걸어볼 차례 입니다.

HW accelerator 의 Native library 는 아래 글에서 설명이 잘 되어 있습니다.


* AES-CBC encryption or decryption operation
    - https://tls.mbed.org/api/aes_8h.html#a321834eafbf0dacb36dac343bfd6b35d


요는 mbedtls 함수를 이용하면, HW accelerator 를 사용할 수 있게 되는군요. 키 포인트는 "mbedtls_aes_crypt_cbc" 함수가 되겠습니다.

int mbedtls_aes_crypt_cbc ( mbedtls_aes_context *	ctx,
							int						mode,
							size_t					length,
							unsigned char			iv[16],
							const unsigned char *	input,
							unsigned char *			output
)


각 변수들의 정의 입니다.


---------------------------------------------------------------------------------------------------
| Parameters | Meaning                                                                            |
---------------------------------------------------------------------------------------------------
|    ctx     | The AES context to use for encryption or decryption.                               |
|            | It must be initialized and bound to a key.                                         |
---------------------------------------------------------------------------------------------------
|    mode    | The AES operation: MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT.                     |
---------------------------------------------------------------------------------------------------
|   length   | The length of the input data in Bytes.                                             |
|            | This must be a multiple of the block size (16 Bytes).                              |
---------------------------------------------------------------------------------------------------
|    iv      | Initialization vector (updated after use).                                         |
|            | It must be a readable and writeable buffer of 16 Bytes.                            |
---------------------------------------------------------------------------------------------------
|   input    | The buffer holding the input data. It must be readable and of size length Bytes.   |
---------------------------------------------------------------------------------------------------
|   output   | The buffer holding the output data. It must be writeable and of size length Bytes. |
---------------------------------------------------------------------------------------------------


아래는 실재 구현에 도움이 될 만한 사이트들 입니다. 예제들이 설명되어 있어요.


* ESP32 Arduino: Encryption using AES-128 in ECB mode
    - https://techtutorialsx.com/2018/04/18/esp32-arduino-encryption-using-aes-128-in-ecb-mode/

* ESP32 Arduino Tutorial: Encryption AES128 in ECB mode
    - https://everythingesp.com/esp32-arduino-tutorial-encryption-aes128-in-ecb-mode/

* How to encrypt data with AES-CBC mode
    - https://tls.mbed.org/kb/how-to/encrypt-with-aes-cbc

재미 있는 것은, "mbedtls/aes.h" 의 library 도 동작하지만,

#include "mbedtls/aes.h"


"hwcrypto/aes.h" 라이브러리도 동일한 parameter 와 동작을 보여줍니다. 함수명에 mbedtls 가 붙느냐, esp가 붙느냐의 차이 뿐.


#include "hwcrypto/aes.h"


위의 두 가지 library 는 따로 설치하지 않아도 되는걸 보면, native library 이면서 서로가 copy 버전이 아닐까 하네요.




6. Hardware AES - 확인


위의 Software AES 를 Hardware AES 용으로 변환하면 되겠지만, 아직 지식이 짧은 관계로 아래 소스를 가지고 확인해 봤습니다.

* Example of using hardware AES 256 Crypto in CBC mode on the ESP32 using ESP-IDF
* cnlohr/esp32_aes_example.c

    - https://gist.github.com/cnlohr/96128ef4126bcc878b1b5a7586c624ef

#include "string.h"
#include "stdio.h"
#include "hwcrypto/aes.h"

/*
For Encryption time: 1802.40us (9.09 MB/s) at 16kB blocks.
*/

static inline int32_t _getCycleCount(void) {
	int32_t ccount;
	asm volatile("rsr %0,ccount":"=a" (ccount));
	return ccount;
}

char plaintext[16384];
char encrypted[16384];

void encodetest() {
	uint8_t key[32];
	uint8_t iv[16];
	
	//If you have cryptographically random data in the start of your payload, you do not need
	//an IV. If you start a plaintext payload, you will need an IV.
	memset( iv, 0, sizeof( iv ) );
	
	//Right now, I am using a key of all zeroes. This should change. You should fill the key
	//out with actual data.
	memset( key, 0, sizeof( key ) );
	
	memset( plaintext, 0, sizeof( plaintext ) );
	strcpy( plaintext, "https://chocoball.tistory.com/entry/Hardware-ESP32-Cryptographic-hardware-acceleration" );
	
	//Just FYI - you must be encrypting/decrypting data that is in BLOCKSIZE chunks!!!
	
	esp_aes_context ctx;
	esp_aes_init( &ctx );
	esp_aes_setkey( &ctx, key, 256 );
	int32_t start = _getCycleCount();
	esp_aes_crypt_cbc( &ctx, ESP_AES_ENCRYPT, sizeof(plaintext), iv, (uint8_t*)plaintext, (uint8_t*)encrypted );
	int32_t end = _getCycleCount();
	
	float enctime = (end-start)/240.0;
	Serial.printf( "Encryption time: %.2fus (%f MB/s)\n", enctime, (sizeof(plaintext)*1.0)/enctime );
	//See encrypted payload, and wipe out plaintext.
	
	memset( plaintext, 0, sizeof( plaintext ) );
	
	int i;
	for( i = 0; i < 128; i++ ) {
		Serial.printf( "%02x[%c]%c", encrypted[i], (encrypted[i]>31)?encrypted[i]:' ', ((i&0xf)!=0xf)?' ':'\n' );
	}
	Serial.printf( "\n" );
	
	//Must reset IV.
	//XXX TODO: Research further: I found out if you don't reset the IV, the first block will fail
	//but subsequent blocks will pass. Is there some strange cryptoalgebra going on that permits this?
	Serial.printf( "IV: %02x %02x\n", iv[0], iv[1] );
	memset( iv, 0, sizeof( iv ) );
	
	//Use the ESP32 to decrypt the CBC block.
	Serial.print("- decryption time [us]: ");
	unsigned long ms = micros ();
	esp_aes_crypt_cbc( &ctx, ESP_AES_DECRYPT, sizeof(encrypted), iv, (uint8_t*)encrypted, (uint8_t*)plaintext );
	Serial.println(micros() - ms);
	
	//Verify output
	for( i = 0; i < 128; i++ ) {
		Serial.printf( "%02x[%c]%c", plaintext[i], (plaintext[i]>31)?plaintext[i]:' ', ((i&0xf)!=0xf)?' ':'\n' );
	}
	Serial.printf( "\n" );
	
	esp_aes_free( &ctx );
}

void setup() {
	// put your setup code here, to run once:
	Serial.begin(115200);
	encodetest();
}

void loop() {
	// put your main code here, to run repeatedly:
}


결과는 다음과 같습니다.

위의 Software AES 와 비슷하게 결과를 내도록 소스를 만들면 확연히 비교할 수 있겠으나, 공부를 더 해야 함.


다만, 최종적인 처리 속도는 결코 아래 결과에서 변하지 않는다는 것을 여러 삽질을 통해 발견했으니 이걸로 만족.



Hardware AES 를 서포트하는 전용 명령어 set 이 최적화가 되지 않아, 이런 결과가 나온 것인지 모르겠네요.

지금으로써는 전용 accelerator 를 사용하지 않고, Software AES 를 구현하는 것이 더 속도적인 이득이 있는 듯 보입니다.


단, 여러가지 일을 동시에 처리해야 할 경우, 암호화/복호화 처리 부분만 따로 분리하여 HW accelerator 를 이용한다면, CPU 부하를 분산시켜 효율적인 활용은 가능할 것 같네요.




FIN


혹시, 위의 Hardware AES 결과가 잘못된 방법으로 검증된 것이라면 댓글로 알려주세요.


esp32_technical_reference_manual_en.pdf



Clock 사이클을 바탕으로 이론적인 계산을 해보면 68ns 레벨이라고, 아래 블로그에서 봤는데, 실측과는 많이 다르군요.


* Pwn the ESP32 crypto-core
    - https://limitedresults.com/2019/08/pwn-the-esp32-crypto-core/


Doing simple math, the HW AES-128 encryption process is 68.75ns (@160MHz).


그렇다고 합니다.


And
prev | 1 | 2 | next