노드 보안
이 가이드의 목표는 악의적인 공격자로부터 노드를 보호하기 위해 취할 수 있는 단계를 안내하는 것입니다. 집에서 로컬 서버를 운영하든 클라우드에서 VPS 서버/가상 머신을 운영하든, 여기에 있는 팁들은 외부 공격에 대비해 노드를 강화하고 수명 기간 동안 보호하는 데 도움이 될 것입니다.
이 섹션에서는 반드시 취해야 하는 필수 조치와 도움이 되지만 필수는 아닌 권장 조치를 모두 설명합니다.
이 가이드는 노드 머신을 강화하기 위해 할 수 있는 일들에 대한 입문서입니다. 커맨드 라인 터미널에 익숙하고 노드를 보호하는 데 더 나아가고 싶다면, 인기 있는 imthenachoman/How-To-Secure-A-Linux-Server 가이드를 참조하세요.
이 가이드의 전제 조건
이 가이드는 노드가 Ubuntu 20.04 LTS를 실행한다고 가정합니다.
개념은 다른 시스템에도 적용되지만 예제 명령어는 그렇지 않을 수 있습니다.
이 가이드의 모든 명령과 마찬가지로, ssh를 사용하여 노드의 커맨드 터미널에 원격으로 연결한다고 가정합니다.
ssh 사용 방법에 대한 복습이 필요하면 먼저 Secure Shell 소개 가이드를 참조하세요.
필수: 클라이언트 머신 보안 유지
Smartnode를 로컬에서 사용하는 경우(키보드와 모니터를 직접 연결하여 물리적으로 로그인하는 경우), 이 섹션은 관련이 없으므로 건너뛸 수 있습니다.
대부분의 Smartnode 운영자는 ssh를 사용하여 다른 컴퓨터에서 노드의 터미널에 연결하여 원격으로 노드와 상호작용합니다:
- 연결 대상 머신(이 경우 노드 머신)을 서버라고 합니다.
- 연결 출발 머신(노트북, 데스크톱 또는 심지어 휴대폰)을 클라이언트라고 합니다.
Smartnode를 보호하기 위해 할 수 있는 가장 중요한 일 중 하나는 클라이언트 머신을 안전하게 유지하는 것입니다. 클라이언트 머신이 손상되고 노드에 로그인하는 데 사용하면 노드에 적용한 대부분의 보안 설정을 우회할 수 있습니다.
예를 들어: 노트북을 SSH 클라이언트로 사용하고 키로거가 설치되어 있다면, SSH를 통해 연결할 때 노드에서 입력하는 비밀 정보(비밀번호 또는 복구 니모닉 등)가 도난당할 것입니다.
클라이언트 머신을 안전하게 유지하는 명확한 가이드는 없지만, 이것이 보안의 한 요소임을 인식하는 것이 좋은 첫 단계입니다. 클라이언트 머신이 가능한 한 안전한지 확인하세요.
다음은 몇 가지 팁입니다:
- 클라이언트 머신을 위험한 활동(신뢰할 수 없는 웹사이트 방문 또는 불필요한 프로그램 설치 등)에 사용하지 마세요
- 클라이언트 머신을 최신 보안 패치로 업데이트 상태를 유지하세요
- 가능하다면 운영 체제에 대한 멀웨어 및 안티바이러스 보호 프로그램을 사용하세요
최대 보안을 위해 SSH 클라이언트로 전용 머신을 사용하고 싶을 수 있지만, 이것이 실용적이지 않을 수 있습니다.
필수: SSH 액세스 보안
Smartnode를 로컬에서 사용하는 경우(키보드와 모니터를 직접 연결하여 물리적으로 로그인하는 경우), 이 섹션은 관련이 없으므로 건너뛸 수 있습니다.
집에서 Smartnode를 실행하든 원격 데이터센터에서 VPS를 사용하든, SSH를 통해 액세스하거나 사용하지 않더라도 SSH가 활성화되어 있을 가능성이 높습니다.
SSH 연결은 안전한 암호화를 기반으로 하지만, 모든 보안 시스템과 마찬가지로 실제 보안은 올바르게 사용하는 데서 나옵니다. SSH 설정에 대해 해야 할 두 가지 주요 작업이 있습니다:
- 사용자 이름과 비밀번호 대신 SSH 키를 사용하여 원격 로그인
- 비밀번호 기반 인증을 완전히 비활성화하여 SSH 키만 원격 로그인 옵션이 되도록
이제 익숙해졌듯이, SSH를 통해 노드에 로그인하는 기본 방법은 사용자 이름과 비밀번호를 사용하는 것입니다. 이것의 단점은 비밀번호가 일반적으로 상당히 "짧고" 무차별 대입 공격에 취약하다는 것입니다.
다행히 SSH를 통해 로그인하는 대안적인 방법이 있습니다: SSH 키 쌍.
SSH 키 쌍은 블록체인 지갑과 유사하게 작동합니다. 공개 부분(지갑 주소와 같은)과 비공개 부분(지갑 주소의 개인 키)이 함께 제공됩니다:
- 공개 부분을 노드에 제공합니다. 이렇게 하면 노드는 당신이 연결할 수 있다는 것을 알고, 정말로 당신이 연결을 시도하고 있다는 것을 알 수 있습니다.
- 비공개 부분은 클라이언트 머신에 보관합니다. 이렇게 하면 당신(그리고 당신만)이 노드에 연결할 수 있습니다.
- 비공개 부분을 비밀번호로 보호할 수 있고(또 그래야 합니다!), 따라서 키를 훔친 사람이 사용할 수 없습니다.
- 컴퓨터의 관점에서 개인 키는 비밀번호보다 기하급수적으로 더 어렵게 해독됩니다. 이는 노드에 대한 무차별 대입 공격의 위험을 완화합니다.
SSH 키 쌍을 만들기 전에 자세히 알아보고 싶다면 다음 링크를 참조하세요:
SSH 키 쌍 생성
클라이언트 머신에서 새 SSH 키 쌍을 생성하는 것으로 시작하겠습니다. 여러 종류의 키가 있지만, 우리는 뛰어난 보안을 제공하는 ed25519라는 키 유형을 사용할 것입니다.
클라이언트 머신에서 다음 명령을 실행하세요(즉, 이미 노드 머신에 SSH로 접속한 상태에서는 실행하지 마세요 - 그렇다면 먼저 SSH를 종료하세요):
다음이 표시됩니다:
이것은 개인 키 파일을 저장할 위치를 묻는 것입니다. SSH는 제공된 기본값과 호환되며 선택하면 자동으로 사용합니다. 그러나 원한다면 다른 것으로 변경할 수 있는 옵션이 있습니다.
경로 /home/username/.ssh/id_ed25519는 사용자 이름이 username이라고 가정한 예시일 뿐입니다.
다른 사용자 이름을 가지고 있을 가능성이 높습니다.
이 가이드에서 위와 같은 경로를 볼 때마다 시스템이 실제 사용자 이름으로 실제로 인쇄하는 경로로 대체하세요.
기본 설정에 만족한다면 Enter를 누르기만 하면 됩니다.
그렇지 않으면 키에 대해 원하는 위치를 입력하세요.
절대 경로여야 합니다(예: Linux에서 /home/username/.ssh/rocketpool_key, OSX에서 /Users/username/.ssh/rocketpool_key).
완료되면 Enter를 누르세요.
Enter를 누른 후 다음이 표시됩니다:
이것은 개인 키 자체의 비밀번호가 됩니다. 노드에 연결하기 위해 키를 사용할 때마다 먼저 이 비밀번호를 입력해야 합니다.
이것을 비워두면 안 됩니다 - 그렇지 않으면 SSH 키 파일을 가진 사람이라면 누구나 사용할 수 있습니다! 당신(그리고 당신만)이 알 수 있는 좋은 비밀번호를 선택하세요.
또한 비밀번호를 잊지 마세요 - 잃어버리면 이 비밀번호를 복구할 방법이 없습니다.
비밀번호 입력을 마치면 Enter를 누르세요.
확인을 위해 다시 입력하라고 요청할 것입니다.
그 후 다음과 같은 출력이 표시됩니다:
첫 번째 줄은 개인 키의 위치를 나타내며, 기본적으로 id_ed25519라고 합니다(파일 확장자가 없음을 주의하세요).
이 개인 키 파일이 기본 위치에 있으면 Ubuntu가 ssh를 사용할 때 자동으로 이 키를 로드합니다.
두 번째 줄은 공개 키의 위치를 나타내며, 기본적으로 id_ed25519.pub라고 합니다.
다음 단계에서 공개 키가 필요합니다.
Ubuntu는 이 새 키를 자동으로 로드 해야 합니다. 그러나 일부 시스템(예: macOS 머신)은 자동으로 로드하지 않습니다 - 클라이언트 머신에서 다음 명령으로 로드하도록 지시해야 합니다:
이것은 이전 단계에서 생성한 개인 키의 경로이며, 공개 키가 아님을 주의하세요. 해당 이전 단계에서 시스템이 인쇄한 경로로 대체하세요.
ssh-agent가 실행되지 않는다는 오류가 발생하면 클라이언트 머신에서 다음 명령을 실행하여 시작하세요:
터미널을 열 때마다 이 두 명령을 입력하고 싶지 않다면 ~/.bashrc 파일에 alias를 추가하여 키를 추가하는 바로 가기를 만들 수 있습니다.
텍스트 에디터를 사용하여 파일을 여세요:
끝에 이 줄을 추가하세요(개인 키에 기본 경로를 사용했다고 가정 - 필요에 따라 업데이트):
Ctrl+O와 Enter, 그 다음 Ctrl+X로 저장하고 종료하세요.
다음으로, 변경 사항을 적용하려면 터미널을 닫고 다시 여세요.
이제 클라이언트 머신에서 loadkey를 입력하여 키를 로드할 수 있습니다.
노드에 공개 키 추가
SSH 키 쌍이 있으면 이제 노드에 공개 키를 추가할 수 있습니다.
이렇게 하면 방금 생성한 개인 키를 사용하여 사용자 이름과 비밀번호 대신 ssh를 통해 연결할 수 있습니다.
이를 수행하는 두 가지 방법이 있습니다 - 하나가 작동하지 않으면 다른 방법을 시도하세요:
참고: 클라이언트 머신이 Windows를 실행 중인 경우 ssh-copy-id를 아직 사용할 수 없습니다.
"수동으로 키 추가" 탭의 지침을 따르세요.
클라이언트 머신에서 다음 명령을 실행하세요:
예를 들어, 노드의 사용자 이름이 staker이고 노드의 IP 주소가 192.168.1.10이라면 다음 명령을 실행할 것입니다:
다음과 같은 메시지가 표시됩니다:
이것은 먼저 키로 로그인을 시도하여 이미 없는지 확인하고 있다는 것을 알려줍니다. 로그인에 실패하면 노드 머신에 새 공개 키를 추가해도 괜찮다는 것을 알게 됩니다.
그런 다음 노드 머신의 사용자 비밀번호를 입력하라는 메시지가 표시됩니다. (이것은 SSH 키의 비밀번호가 아닙니다!)
사용자 비밀번호를 입력하면 다음 출력이 표시됩니다:
작동했다는 의미입니다!
이제 평소처럼 노드에 ssh로 접속할 수 있지만, 이제 사용자 계정의 비밀번호를 입력할 필요가 없습니다.
대신 SSH 개인 키의 비밀번호를 입력해야 합니다. 시스템 설정에 따라 재시작당 한 번만 수행하면 되거나, 노드에 연결하기 위해 키를 사용할 때마다 수행해야 할 수 있습니다.
비밀번호를 통한 로그인 비활성화
SSH 키 쌍을 설정했더라도 노드는 여전히 다른 머신이 사용자 이름과 비밀번호 방법을 사용하여 로그인하려고 시도하도록 허용합니다. 이것은 SSH 키를 사용하는 전체 목적을 무효화하므로 다음 단계는 이를 비활성화하는 것입니다.
SSH 서버의 구성을 수정하려고 합니다. 기존 SSH 세션은 모두 보존됩니다. 그러나 실수를 하면 새로운 SSH 세션을 더 이상 만들 수 없게 되어 효과적으로 머신에서 잠길 수 있습니다.
이를 방지하기 위해 다음 단계를 위해 2개의 SSH 세션을 만드는 것을 강력히 권장합니다 - 하나는 편집과 테스트용이고, 다른 하나는 중단 변경 사항을 되돌릴 수 있는 백업용입니다.
평소처럼 ssh를 사용하여 머신에 로그인하는 것으로 시작하세요:
상기시켜드리자면, 만약을 대비해 두 개의 별도 터미널에서 두 번 수행해야 합니다. 백업 세션은 지금은 무시할 수 있습니다 - 필요할 때 알려드리겠습니다. 다음 명령은 첫 번째 세션에서만 실행하세요.
SSH 서버의 구성 파일을 여세요:
sudo로 시작하는 모든 명령과 마찬가지로 사용자 계정의 비밀번호를 입력하라는 메시지가 표시됩니다.
이것은 큰 파일이므로 키보드의 화살표 키나 Page Up / Page Down을 사용하여 탐색해야 합니다.
다음 변경 사항을 수행하세요:
#AuthorizedKeysFile이 주석 처리되어 있으면 주석 해제(앞의#제거)KbdInteractiveAuthentication yes를KbdInteractiveAuthentication no로 변경하고 주석 해제(앞의#제거) - 이전 버전의 SSH는 이 옵션을KbdInteractiveAuthentication대신ChallengeResponseAuthentication이라고 부릅니다PasswordAuthentication yes를PasswordAuthentication no로 변경하고 주석 해제(앞의#제거)PermitRootLogin yes를PermitRootLogin prohibit-password로 변경(이미 설정되어 있고 앞에#이 있는 경우 제외)
완료되면 Ctrl+O와 Enter로 저장한 다음 Ctrl+X로 종료하세요.
마지막으로 sudo sshd -T | grep -i passwordauthentication을 실행하고 passwordauthentication no를 출력하는지 확인하세요.
그렇지 않으면 sudo nano /etc/ssh/sshd_config.d/50-cloud-init.conf를 실행하여 해당 파일에서도 PasswordAuthentication yes를 PasswordAuthentication no로 설정해야 할 수 있습니다.
이전처럼 Ctrl+O와 Enter, 그 다음 Ctrl+X로 저장하고 종료하세요
다음으로, 새 설정을 적용하도록 SSH 서버를 다시 시작하세요:
이 후 사용자 이름과 비밀번호를 통한 SSH 로그인이 비활성화되어야 합니다.
이 시점에서 SSH 세션을 종료하고 다시 SSH로 접속을 시도해야 합니다. 성공적으로 다시 접속할 수 있다면 SSH 구성이 여전히 유효합니다!
다시 접속할 수 없다면 구성에 문제가 발생한 것입니다.
이 섹션의 시작 부분에서 만든 백업 SSH 세션을 사용하여 /etc/ssh/sshd_config 파일을 수정하세요.
실수를 찾거나 변경 사항을 취소한 다음 sudo systemctl restart sshd를 사용하여 SSH 서버를 다시 시작하세요.
다시 시작한 후 "다른" 터미널에서 SSH로 다시 연결을 시도하세요. 다시 작동하여 성공적으로 연결할 수 있을 때까지 이 작업을 계속하세요.
(선택 사항) 2단계 인증 활성화
2단계 인증은 비밀번호나 SSH 키 외에 두 번째 보안 조치를 요구하는 것으로, 일반적으로 주 장치와 별도의 장치에서 수행됩니다.
예를 들어, 암호화폐 거래소와 같은 웹사이트에 비밀번호와 Google Authenticator 코드(또는 SMS 코드)를 모두 사용하여 로그인하는 것에 익숙할 수 있습니다. 이 2단계 프로세스는 2단계 인증의 예입니다.
SSH도 Google Authenticator 코드를 요구하도록 구성할 수 있으며, 이는 공격자가 어떻게든 SSH 키와 암호문을 손상시켰더라도 여전히 인증 앱이 있는 장치(아마도 휴대폰)가 필요하다는 것을 의미합니다. 이것은 시스템에 추가 보안 계층을 추가합니다.
뭔가 잘못 구성할 경우를 대비해 노드에 대한 SSH 연결이 있는 두 번째 터미널을 여는 것을 강력히 권장합니다. 이렇게 하면 자신을 잠그는 경우에도 여전히 연결되어 있는 백업이 있어 실수를 쉽게 취소할 수 있습니다.
자신을 잠그는 경우 로컬 모니터와 키보드를 통해 노드에 물리적으로 액세스하여 로그인하고 잘못된 구성을 복구해야 합니다.
아직 없다면 휴대폰에 Google Authenticator(또는 호환되는 동등품)를 설치하는 것으로 시작하세요. Android 사용자의 경우 비밀번호 잠금 및 편리한 백업을 지원하는 오픈 소스 대안인 andOTP를 고려하세요.
다음으로, 이 명령으로 노드에 Google Authenticator 모듈을 설치하세요:
이제 PAM(플러그 가능한 인증 모듈)에 이 모듈을 사용하도록 지시하세요.
먼저 구성 파일을 여세요:
@include common-auth를 찾아(맨 위에 있어야 함) 앞에 #을 추가하여 주석 처리하세요:
다음으로, 파일 맨 위에 다음 줄을 추가하세요:
그런 다음 Ctrl+O, Enter, Ctrl+X로 파일을 저장하고 종료하세요.
이제 PAM이 Google Authenticator를 사용하도록 알았으므로 다음 단계는 sshd에 PAM을 사용하도록 지시하는 것입니다.
sshd 구성 파일을 여세요:
이제 KbdInteractiveAuthentication no 줄을 KbdInteractiveAuthentication yes로 변경하여 다음과 같이 보이도록 하세요:
(이전 버전의 SSH는 이 옵션을 KbdInteractiveAuthentication 대신 ChallengeResponseAuthentication이라고 부릅니다.)
파일 맨 아래에 다음 줄을 추가하세요. 이것은 sshd에 SSH 키와 Google Authenticator 코드가 모두 필요하다는 것을 나타냅니다:
그런 다음 Ctrl+O, Enter, Ctrl+X로 파일을 저장하고 종료하세요.
이제 sshd가 설정되었으므로 2FA 코드를 생성해야 합니다.
터미널에서 다음을 실행하세요:
먼저 시간 기반 토큰에 대해 묻습니다.
이 질문에 y라고 답하세요:
이제 화면에 큰 QR 코드가 표시됩니다. Google Authenticator 앱으로 스캔하여 추가하세요. 또한 다음과 같이 비밀과 몇 가지 백업 코드도 표시됩니다:
2FA 앱이 없을 때 머신에 로그인해야 하는 경우를 대비해 비상 스크래치 코드를 안전한 곳에 기록하세요. 앱이 없으면 더 이상 머신에 SSH로 접속할 수 없습니다!
마지막으로, 몇 가지 추가 매개변수를 묻습니다. 권장되는 기본값은 다음과 같습니다:
완료되면 새 설정을 적용하도록 sshd를 다시 시작하세요:
SSH 키로 서버에 SSH로 접속하려고 하면 이제 2FA 인증 코드도 요청받지만 비밀번호는 요청받지 않습니다.
필수: 자동 보안 업데이트 활성화
운영 체제 공급업체는 정기적으로 업데이트 및 보안 수정 사항을 게시하므로 시스템을 최신 패치로 업데이트 상태로 유지하는 것이 중요합니다. 이를 수행하는 가장 쉬운 방법은 자동 업데이트를 활성화하는 것입니다.
노드 머신에서 다음 명령을 실행하세요:
/etc/apt/apt.conf.d/20auto-upgrades를 편집하여 자동 업데이트 설정을 변경할 수 있습니다:
다음은 합리적인 자동 업데이트 설정의 예입니다:
변경 사항 추가가 완료되면 Ctrl+O와 Enter로 저장한 다음 Ctrl+X로 종료하세요.
그 후 새 설정을 로드해야 합니다:
필수: 방화벽 활성화
일반적으로 머신은 Execution 클라이언트, Consensus 클라이언트 및 Smartnode 스택이 사용하는 포트에서만 네트워크 트래픽을 수락해야 합니다. 이를 시행하고 예상치 못한 또는 바람직하지 않은 트래픽을 방지하기 위해 노드에 방화벽을 설치할 수 있습니다.
Rocketpool 설정 중에 다른 execution/consensus 클라이언트 포트를 선택한 경우 아래 포트를 설정에 맞게 편집해야 합니다.
Ubuntu는 기본적으로 ufw(uncomplicated fire wall)가 설치되어 있으며, 이는 노드의 방화벽 설정을 관리하기 위한 편리한 유틸리티입니다.
다음 명령은 Smartnode에 대한 좋은 기본 구성으로 ufw를 설정합니다.
노드 머신에서 이를 실행하세요.
명시적으로 허용하지 않는 한 연결을 비활성화하세요:
SSH 허용:
Execution 클라이언트 허용(이전에 ETH1이라고 불림):
Consensus 클라이언트 허용(이전에 ETH2라고 불림):
lighthouse 클라이언트 v4.5.0+를 실행하는 경우 quic 프로토콜을 사용하여 지연 시간을 줄이고/대역폭을 늘릴 수 있으며, quic 프로토콜은 기본적으로 lighthouse의 --port + 1을 사용하여 quic 메시지를 수신합니다: https://lighthouse-blog.sigmaprime.io/Quic,%20Networking.html
마지막으로 ufw를 활성화하세요:
iptables 전문가는 Docker가 ufw 설정을 우회한다는 점을 알 수 있습니다.
엄밀히 말하면, Hybrid 모드로 실행하지 않는 한 Execution 및 Consensus 클라이언트 규칙이 필요하지 않다는 의미입니다.
그러나 추가해도 단점이 없으며 Hybrid 모드로 전환하는 경우 방화벽 문제가 발생하지 않도록 합니다.
(선택 사항) 무차별 대입 및 DDoS 보호 활성화
DDoS 공격과 무차별 대입 연결 시도로부터 서버를 보호하려면 fail2ban을 설치할 수 있습니다.
이 프로그램은 들어오는 연결을 모니터링하고 잘못된 자격 증명으로 반복적으로 로그인을 시도하는 IP 주소를 차단합니다.
침입 방지에 대한 자세한 내용은 이 가이드를 참조하세요.
노드 머신에서 다음 명령을 실행하세요:
서비스 설치:
다음으로 /etc/fail2ban/jail.d/ssh.local을 여세요:
다음 내용을 추가하세요:
maxretry 설정을 변경할 수 있으며, 이는 문제가 있는 주소를 잠그기 전에 허용할 시도 횟수입니다.
완료되면 Ctrl+O와 Enter로 저장한 다음 Ctrl+X로 종료하세요.
마지막으로 서비스를 다시 시작하세요:
이것으로 노드의 보안 태세를 크게 향상시켰습니다. 축하합니다!