Bitcoin w klatce?

Zdarzyło się, że z zawodu jestem administratorem systemów komputerowych i sieci (krótko: admin), i miałem okazję zająć się przez nieco ponad 10 lat różnorodnymi systemami, w tym tymi, które wymagają [po|za]wyższonych środków bezpieczeństwa. A także, że jakiś czas temu zainteresowałem się bitcoinem, i nie tylko go używałem, ale również uruchomiłem kilka mikroserwisów, aby nauczyć się samodzielnie pracować z siecią bitcoina (to także p2p) z perspektywy dewelopera (właściwie nie jestem zbyt dobry w tym, dev, więc tak, przechodziłem obok). Ale nie o rozwoju mówię, lecz o bezpiecznym i efektywnym środowisku dla aplikacji.

Technologie finansowe (fintech) idą w parze z bezpieczeństwem informacji (infosec) i jedno bez drugiego może działać, ale nie na długo. Dlatego chcę podzielić się swoim doświadczeniem i zestawem narzędzi, które używam, obejmującym zarówno fintech, jak i infosec, a także mogącym być używanym w szerszym lub zupełnie innym kontekście. W tym artykule opowiem nie tyle o bitcoinie, ile o modelu infrastruktury dla rozwoju i eksploatacji usług finansowych (i nie tylko) — jednym słowem tych usług, w których „B” ma znaczenie. To odnosi się zarówno do giełdy bitcoinowej, jak i do typowego korporacyjnego zoo serwisów małej firmy niezwiązanej z bitcoinem.

Chcę zauważyć, że jestem zwolennikiem zasad „keep it stupid simple” i „less is more”, dlatego zarówno artykuł, jak i opisana w nim treść będą posiadały cechy, o których mówią te zasady.

Wyobrażony scenariusz: Zacznijmy od przykładu wymiany bitcoinów. Postanowiliśmy uruchomić wymianę rubli, dolarów, euro na bitcoiny i z powrotem, a nasze rozwiązanie już działa. Mamy również wszystkie kwestie prawne załatwione dla innych kryptowalut, takich jak Qiwi i WebMoney, tzn. mamy gotową aplikację, która działa jako bramka płatnicza dla rubli, dolarów i euro oraz innych systemów płatności. Ta aplikacja jest połączona z naszymi kontami bankowymi i ma pewne API dla naszych końcowych aplikacji. Ponadto mamy aplikację webową, która pełni rolę wymiennika dla użytkowników, podobnie jak typowe konta Qiwi czy WebMoney — zakładacie konto, dodajecie kartę itd. Komunikuje się z naszą bramką przy użyciu REST API w lokalnej sieci. Postanowiliśmy dodać bitcoiny i przy okazji zmodernizować infrastrukturę, ponieważ początkowo wszystko zostało szybko uruchomione na virtualboxach pod biurkiem… strona zaczęła być używana, a my zaczęliśmy martwić się o uptime i wydajność.

Zacznijmy od podstaw — wybór serwera. Ponieważ biznes w naszym przykładzie jest mały i ufamy dostawcy usług hostingowych (OVH), wybierzemy budżetową opcję , w której nie można zainstalować systemu z oryginalnego obrazu .iso, ale nic strasznego, dział IT na pewno przeprowadzi analizę zainstalowanego obrazu. A gdy urośniemy, wynajmiemy własną szafkę zamykaną na klucz z ograniczonym dostępem fizycznym, a może nawet wybudujemy nasze własne centrum danych. W każdym razie warto pamiętać, że wynajmując sprzęt i instalując gotowe obrazy, istnieje szansa, że w waszym systemie będzie „trojan od dostawcy”, który w większości przypadków nie służy do szpiegowania, ale do zapewnienia bardziej wygodnych narzędzi do zarządzania serwerem.

Instalacja serwera

To proste. Wybieramy sprzęt, który odpowiada naszym potrzebom. Następnie wybieramy obraz FreeBSD. Możemy też połączyć się (w przypadku innego dostawcy i własnego sprzętu) przez IPMI lub z monitorem i załadować obraz .iso FreeBSD do bootowania. Do instalacji orkiestralnej używam Ansible i mfsbsd. Jedyną różnicą jest to, że w naszym przypadku z Kimsufi wybraliśmy instalację niestandardową , aby dwa dyski w macierzy miały „otwarte” tylko partycje rozruchowe i /home, pozostała część przestrzeni dysku będzie zaszyfrowana, ale o tym później.

Bitcoin w klatce?

Instalacja systemu odbywa się w standardowy sposób, nie będę się na tym zatrzymywał, tylko zaznaczam, że przed rozpoczęciem eksploatacji warto zwrócić uwagę na twardość opcje, które oferuje bsdinstaller pod koniec instalacji (jeśli instalujesz system samodzielnie):

Bitcoin w klatce?

Tak dobry materiał na ten temat, w skrócie go tutaj powtórzę.

Wymienione powyżej parametry można również włączyć na już zainstalowanym systemie. W tym celu należy edytować plik bootloadera i włączyć parametry jądra. *ee — to taki edytor w BSD

# ee /etc/rc.conf

...
#sec hard
clear_tmp_enable="YES"
syslogd_flags="-ss"    
sendmail_enable="NONE"

# ee /etc/sysctl.conf

...
#sec hard
security.bsd.see_other_uids=0
security.bsd.see_other_gids=0
security.bsd.unprivileged_read_msgbuf=0
security.bsd.unprivileged_proc_debug=0
kern.randompid=$(jot -r 1 9999)
security.bsd.stack_guard_page=1

Należy również upewnić się, że masz zainstalowaną najnowszą wersję systemu oraz zrealizować wszystkie aktualizacje i upgrade'y. W naszym przypadku na przykład konieczna jest aktualizacja do najnowszej wersji, ponieważ obrazy wstępne są o pół roku do roku w tyle. I tam zmieniamy port SSH na inny niż domyślny, dodajemy autoryzację za pomocą kluczy i wyłączamy logowanie hasłem.

Następnie konfigurujemy aide, monitorowanie stanu plików konfiguracyjnych systemu. O tym można przeczytać bardziej szczegółowo tutaj.

pkg install aide

i edytujemy nasz crontab

crontab -e

06 01 * * 0-6 /root/chkaide.sh

#! /bin/sh
#chkaide.sh
MYDATE=`date +%Y-%m-%d`
MYFILENAME="Aide-"$MYDATE.txt
/bin/echo "Aide check !! `date`" > /tmp/$MYFILENAME
/usr/local/bin/aide --check > /tmp/myAide.txt
/bin/cat /tmp/myAide.txt|/usr/bin/grep -v failed >> /tmp/$MYFILENAME
/bin/echo "**************************************" >> /tmp/$MYFILENAME
/usr/bin/tail -20 /tmp/myAide.txt >> /tmp/$MYFILENAME
/bin/echo "****************DONE******************" >> /tmp/$MYFILENAME

Włączamy audyt systemowy

sysrc auditd_enable=YES

# service auditd start

Jak to administrować doskonale opisano w przewodniku.

Teraz uruchamiamy ponownie i przystępujemy do oprogramowania na serwerze. Każdy serwer jest hyperwizorem dla kontenerów lub pełnych maszyn wirtualnych. Dlatego ważne jest, aby procesor wspierał VT-x i EPT, jeśli planujemy używać pełnej wirtualizacji.

Jako menedżera kontenerów i maszyn wirtualnych używam cbsd od olevole, życzę mu duże zdrowie i błogosławieństw za tę wspaniałą narzędzie!

Kontenery? Znowu docker?

A oto i nie. FreeBSD Jails — to doskonałe narzędzie do konteneryzacji, a wspomniany cbsd do orkiestracji tych kontenerów, których nazwą — komórki.

Klatka to niezwykle efektywne rozwiązanie do budowy infrastruktury dla różnych celów, gdzie konieczna jest całkowita izolacja poszczególnych usług lub procesów. W zasadzie to klon systemu hosta, ale nie wymaga pełnej wirtualizacji sprzętu. Dzięki temu zasoby nie są marnowane na "system operacyjny gościa", a jedynie na wykonywaną pracę. Kiedy klatki są używane do celów wewnętrznych, to wygodne rozwiązanie dla optymalnego wykorzystania zasobów — wiele klatek na jednym serwerze fizycznym może korzystać z całych zasobów serwera w razie potrzeby. Biorąc pod uwagę, że różnym pod usługom potrzebne są dodatkowe zasoby w różnym czasie, można maksymalnie zwiększyć wydajność jednego serwera, jeśli odpowiednio zaplanuje się i rozłoży klatki między serwerami. W razie potrzeby klatkom można również nałożyć ograniczenia dotyczące wykorzystania zasobów.

Bitcoin w klatce?

A co z pełną wirtualizacją?

O ile mi wiadomo, cbsd obsługuje pracę bhyve i hipernadzorców XEN. Z drugiego nigdy nie korzystałem, a ten pierwszy to stosunkowo młody hipernadzorca od FreeBSD.Przykład użycia rozważymy bhyve w przykładzie poniżej.

Instalacja i konfiguracja środowiska hosta

Używamy FS ZFS. To niezwykle potężne narzędzie do zarządzania przestrzenią na serwerze. Dzięki ZFS można bezpośrednio z dysków tworzyć macierze w różnych konfiguracjach, dynamicznie rozszerzać przestrzeń „na gorąco”, wymieniać uszkodzone dyski, zarządzać migawkami i wiele, wiele innych rzeczy, które można opisać w całej serii artykułów. Wróćmy do naszego serwera i jego dysków. Na początku instalacji na dyskach pozostawiliśmy wolne miejsce na zaszyfrowane partycje. Dlaczego tak? Aby system automatycznie się uruchamiał i nasłuchiwał po SSH.

gpart add -t freebsd-zfs /dev/ada0

/dev/ada0p4 added!

dodajemy partycję dysku na pozostałe miejsce

geli init /dev/ada0p4

wprowadzamy nasze hasło szyfrowania

geli attach /dev/ada0p4

ponownie wprowadzamy hasło i pojawia się urządzenie /dev/ada0p4.eli — to nasze zaszyfrowane miejsce. Następnie powtarzamy to samo dla /dev/ada1 i pozostałych dysków w macierzy. I tworzymy nowy ZFS pool.

zpool create vms mirror /dev/ada0p4.eli /dev/ada1p4.eli /dev/ada3p4.eli — no to mamy gotowy minimalny zestaw bojowy. Lustrzana macierz dysków na wypadek, gdyby jeden z trzech uległ awarii.

Tworzymy zestaw danych na nowym „pulu”

zfs create vms/jails

pkg install cbsd — uruchamiamy polecenie i instalujemy zarządzanie dla naszych kontenerów.

Po tym jak cbsd zostanie zainstalowane, należy je zainicjować:

# env workdir="/vms/jails" /usr/local/cbsd/sudoexec/initenv

no i odpowiadamy na wiele pytań, głównie domyślnymi odpowiedziami.

*Jeśli używasz szyfrowania, ważne jest, aby demon cbsdd nie uruchamiał się automatycznie, dopóki nie odblokujesz dysków ręcznie lub automatycznie (w naszym przykładzie robi to zabbix)

**Również nie używam NAT z cbsd, a konfiguruję go samodzielnie w pf.

# sysrc pf_enable=YES

# ee /etc/pf.conf

IF_PUBLIC="em0"
IP_PUBLIC="1.23.34.56"
JAIL_IP_POOL="192.168.0.0/24"

#WHITE_CL="{ 127.0.0.1 }"

icmp_types="echoreq"

set limit { states 20000, frags 20000, src-nodes 20000 }
set skip on lo0
scrub in all

#NAT dla kontenerów
nat pass on $IF_PUBLIC from $JAIL_IP_POOL to any -> $IP_PUBLIC

## Przekierowanie portu sieci Bitcoin
IP_JAIL="192.168.0.1"
PORT_JAIL="{8333}"
rdr pass on $IF_PUBLIC proto tcp from any to $IP_PUBLIC port $PORT_JAIL -> $IP_JAIL

# service pf start

# pfctl -f /etc/pf.conf

Konfiguracja polityk zapory to także osobny temat, dlatego nie będę zagłębiać się w konfigurację polityki BLOCK ALL i ustawienia białych list — można to zrobić, czytając dokumentację oficjalną lub jeden z wielu dostępnych artykułów w Google.

Cóż... mamy zainstalowane cbsd, czas stworzyć naszego pierwszego konia roboczego — demona bitcoina w kontenerze!

cbsd jconstruct-tui

Bitcoin w klatce?

Tutaj widzimy dialog tworzenia kontenera. Po ustawieniu wszystkich wartości, tworzymy!

Podczas tworzenia pierwszego kontenera, należy wybrać, co użyć jako bazę dla kontenerów. Wybieram dystrybucję z repozytorium FreeBSD poleceniem repo. Tego wyboru dokonuje się tylko podczas tworzenia pierwszego kontenera konkretnej wersji (można hostować kontenery dowolnych wersji, które są starsze od wersji hosta).

Po zainstalowaniu wszystkiego — uruchamiamy kontener!

# cbsd jstart bitcoind

Ale musimy zainstalować oprogramowanie w kontenerze.

# jls

   JID  IP Address      Hostname                      Path
     1  192.168.0.1     bitcoind.space.com            /zroot/jails/jails/bitcoind

jexec bitcoind aby wejść do konsoli kontenera

i już wewnątrz kontenera instalujemy oprogramowanie wraz z jego zależnościami (nasz system hosta pozostaje czysty)

bitcoind:/@[15:25] # pkg install bitcoin-daemon bitcoin-utils

bitcoind:/@[15:30] # sysrc bitcoind_enable=YES

bitcoind:/@[15:30] # service bitcoind start

Bitcoin w kontenerze jest, ale potrzebujemy anonimowości, ponieważ chcemy łączyć się z niektórymi kontenerami przez sieć TOR. A w ogóle planujemy, aby większość kontenerów z podejrzanym oprogramowaniem działała tylko przez proxy. Dzięki pf Można wyłączyć NAT dla określonego zakresu adresów IP w sieci lokalnej i zezwolić na NAT tylko dla naszego węzła TOR. Dzięki temu, nawet jeśli do klatki trafi złośliwe oprogramowanie, prawdopodobnie nie nawiąże ono kontaktu ze światem zewnętrznym, a jeśli już to zrobi, nie ujawni IP naszego serwera. Dlatego tworzymy jeszcze jedną klatkę, aby „przekierować” usługi jak serwis „.onion” i jako proxy do wyjścia do internetu dla osobnych klatek.

# cbsd jsconstruct-tui

# cbsd jstart tor

# jexec tor

tor:@[15:38] # pkg install tor

tor:@[15:38] # sysrc tor_enable=YES

tor:@[15:38] # ee /usr/local/etc/tor/torrc

Ustawiamy nasłuchiwanie na lokalnym adresie (dostępne dla wszystkich klatek)

SOCKSPort 192.168.0.2:9050

Czego nam jeszcze brakuje do pełni szczęścia? Tak, potrzebujemy usługi dla naszego weba, może nawet więcej niż jednej. Uruchomimy nginx, który będzie pełnił rolę reverse-proxy i dbał o przedłużanie certyfikatów Let’s Encrypt.

# cbsd jsconstruct-tui

# cbsd jstart nginx-rev

# jexec nginx-rev

nginx-rev:@[15:47] # pkg install nginx py36-certbot

I oto 150 MB zależności umieściliśmy w klatce. A host wciąż pozostaje czysty.

Wrócimy do konfiguracji nginx później, musimy jeszcze uruchomić dwie klatki dla naszego bramki płatniczej na nodejs i rust oraz aplikacji webowej, która z jakiegoś powodu działa na apache i PHP, a dodatkowo potrzebuje bazy danych MySQL.

# cbsd jsconstruct-tui

# cbsd jstart paygw

# jexec paygw

paygw:@[15:55] # pkg install git node npm

paygw:@[15:55] # curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

… i jeszcze 380 MB pakietów w izolacji.

Następnie pobieramy nasze aplikacje za pomocą gita i uruchamiamy je.

# cbsd jsconstruct-tui

# cbsd jstart webapp

# jexec webapp

webapp:@[16:02] # pkg install mariadb104-server apache24 php74 mod_php74 php74-pdo_mysql

450 MB pakietów. w klatce.

Tutaj dajemy dostęp deweloperowi po SSH bezpośrednio do klatki, oni sami wszystko zrobią:

webapp:@[16:02] # ee /etc/ssh/sshd_config

Port 2267 — zmieniamy port SSH klatki na dowolny losowy

webapp:@[16:02] # sysrc sshd_enable=YES

webapp:@[16:02] # service sshd start

No i proszę, usługa uruchomiona, musimy tylko dodać regułę do pf firewall

Zobaczmy, jakie IP mają klatki i jak w ogóle wygląda nasza ‘lokalna sieć’

# jls

   JID  IP Address      Hostname                      Path
     1  192.168.0.1     bitcoind.space.com            /zroot/jails/jails/bitcoind
     2  192.168.0.2     tor.space.com                 /zroot/jails/jails/tor
     3  192.168.0.3     nginx-rev.space.com           /zroot/jails/jails/nginx-rev
     4  192.168.0.4     paygw.space.com               /zroot/jails/jails/paygw
     5  192.168.0.5     webapp.my.domain              /zroot/jails/jails/webapp

i dodamy regułę

# ee /etc/pf.conf

## SSH for web-Devs
IP_JAIL="192.168.0.5"
PORT_JAIL="{ 2267 }"
rdr pass on $IF_PUBLIC proto tcp from any to $IP_PUBLIC port $PORT_JAIL -> $IP_JAIL

no i skoro już tutaj jesteśmy, dodamy także regułę do reverse-proxy:

## web-ports for nginx-rev
IP_JAIL="192.168.0.3"
PORT_JAIL="{ 80, 443 }"
rdr pass on $IF_PUBLIC proto tcp from any to $IP_PUBLIC port $PORT_JAIL -> $IP_JAIL

# pfctl -f /etc/pf.conf

A teraz trochę o bitcoinach

Co mamy — mamy aplikację webową, która jest dostępna z zewnątrz, i która lokalnie łączy się z naszą bramką płatniczą. Teraz musimy przygotować środowisko do interakcji z siecią bitcoina — węzeł bitcoind to tylko demon, który wspiera lokalną kopię blockchaina akutalnej. Ten demon posiada RPC i funkcjonalność portfela, jednak do opracowywania aplikacji istnieją bardziej wygodne „opakowania”. Na początek postanowiliśmy zainstalować electrum — to portfel CLI. Ten portfel będzie używany przez nas jako „zimne przechowywanie” dla naszych bitcoinów — ogólnie te bitcoiny, które muszą być przechowywane „poza” systemem dostępnym dla użytkowników i w ogóle z dala od wszystkich. Posiada również GUI, więc taki sam portfel zamierzamy używać na
naszych laptopach. Na razie będziemy używać Electrum z publicznymi serwerami, a później podniesiemy jeszcze jednego instancję w innej klatce, aby całkowicie nie być od nikogo zależni. ElectrumX, żeby całkowicie nie być od nikogo zależni.

# cbsd jsconstruct-tui

# cbsd jstart electrum

# jexec electrum

electrum: /@[8:45] # pkg install py36-electrum

jeszcze 700 MB oprogramowania mamy w klatce

electrum: /@[8:53] # adduser

Nazwa użytkownika: wallet
Pełna nazwa: 
Uid (Zostaw puste dla domyślnej): 
Grupa logowania [wallet]: 
Grupa logowania to wallet. Zainvite wallet do innych grup? []: 
Klasa logowania [default]: 
Powłoka (sh csh tcsh nologin) [sh]: tcsh
Katalog domowy [ /home /wallet]: 
Uprawnienia katalogu domowego (Zostaw puste dla domyślnych): 
Czy używać uwierzytelniania opartego na haśle? [yes]: no
Czy zablokować konto po utworzeniu? [no]: 
Nazwa użytkownika   : wallet
Hasło   : 
Pełna nazwa  : 
Uid        : 1001
Klasa      : 
Grupy     : wallet 
Dom       : /home/wallet
Tryb domowy  : 
Powłoka      : /bin/tcsh
Zablokowane     : no
OK? (yes /no): yes
adduser: INFO: Pomyślnie dodano (wallet) do bazy użytkowników.
Czy dodać innego użytkownika? (yes/no): no
Do widzenia!
electrum: /@[8:53] # su wallet

electrum: /@[8:53] # su wallet

wallet@electrum: / % electrum-3.6 create

{
    "msg": "Proszę przechowywać swój seed w bezpiecznym miejscu; jeśli go stracisz, nie będziesz w stanie przywrócić swojego portfela.",
    "path": "/usr/home/wallet/.electrum/wallets/default_wallet",
    "seed": "zazdrosny świnia materiał wstążka młody cios wizualny okej kaktus losowy ptak"
}

Teraz mamy stworzony portfel.

wallet@electrum: / % electrum-3.6 listaddresses

[
    "18WEhbjvMLGRMfwudzUrUd25U5C7uZYkzE",
    "14XHSejhxsZNDRtk4eFbqAX3L8rftzwQQU",
    "1KQXaN8RXiCN1ne9iYngUWAr6KJ6d4pPas",
    ...
    "1KeVcAwEYhk29qEyAfPwcBgF5mMMoy4qjw",
    "18VaUuSeBr6T2GwpSHYF3XyNgLyLCt1SWk"
]

wallet@electrum: / % electrum-3.6 help

Do naszego on-chain portfela będą mogły podłączyć się tylko ograniczone osoby. Aby nie otwierać dostępu na zewnątrz do tej klatki, połączenia po SSH będą odbywały się przez TOR (taki zdecentralizowany odpowiednik VPN). Uruchamiamy SSH w klatce, ale nie dotykamy naszego pf.conf na hoście.

electrum: /@[9:00] # sysrc sshd_enable=YES

electrum: /@[9:00] # service sshd start

Teraz wyłączymy klatkę z portfelem z dostępu do Internetu. Ustawimy jej adres IP z innej przestrzeni podsieci, która nie jest NAT-owana. Najpierw zmienimy /etc/pf.conf na hoście

# ee /etc/pf.conf

JAIL_IP_POOL="192.168.0.0/24" zmienimy na JAIL_IP_POOL="192.168.0.0/25", w ten sposób wszystkie adresy 192.168.0.126-255 nie będą miały bezpośredniego dostępu do internetu. Tak zwana sieć „air-gap” w oprogramowaniu. Reguła NAT pozostaje taka sama

nat pass on $IF_PUBLIC from $JAIL_IP_POOL to any -> $IP_PUBLIC

Przeładowujemy reguły

# pfctl -f /etc/pf.conf

Teraz zajmiemy się naszą klatką

# cbsd jconfig jname=electrum

Bitcoin w klatce?

Bitcoin w klatce?

jset mode=quiet jname=electrum ip4_addr="192.168.0.200"
Usuń stary adres IP: /sbin/ifconfig em0 inet 192.168.0.6 -alias
Skonfiguruj nowy adres IP: /sbin/ifconfig em0 inet 192.168.0.200 alias
ip4_addr: 192.168.0.200

Hmm, ale teraz przestanie działać sama system. Możemy jednak wskazać systemowy proxy. Ale jest jeden kwiatek, na TOR to proxy SOCKS5, a dla wygody chcielibyśmy jeszcze proxy HTTP.

# cbsd jsconstruct-tui

# cbsd jstart polipo

# jexec polipo

polipo:/@[9:28] # pkg install polipo

polipo:/@[9:28] # ee /usr/local/etc/polipo/config

socksParentProxy = "192.168.0.2:9050"
socksProxyType = socks5

polipo:/@[9:42] # sysrc polipo_enable=YES

polipo:/@[9:43] # service polipo start

No więc, mamy teraz w naszym systemie dwa serwery proxy, oba przez TOR: socks5://192.168.0.2:9050 i http://192.168.0.6:8123

Teraz możemy skonfigurować środowisko naszego portfela

# jexec electrum

electrum:/@[9:45] # su wallet

wallet@electrum:/ % ee ~/ .cshrc

#in the end of file proxy config
setenv http_proxy http://192.168.0.6:8123
setenv https_proxy http://192.168.0.6:8123

No więc, teraz shell będzie działał pod proxy. Jeśli chcemy instalować pakiety, warto dodać do /usr/local/etc/pkg.conf z poziomu roota klatki

pkg_env: {
               http_proxy: "http://my_proxy_ip:8123",
           }

A teraz nadszedł czas aby dodać usługę ukrytą TOR jako adres naszego serwisu SSH w klatce portfela.

# jexec tor

tor:/@[9:59] # ee /usr/local/etc/tor/torrc

HiddenServiceDir /var/db/tor/electrum/
HiddenServicePort 22 192.168.0.200:22

tor:/@[10:01] # mkdir /var/db/tor/electrum

tor:/@[10:01] # chown -R _tor:_tor /var/db/tor/electrum

tor:/@[10:01] # chmod 700 /var/db/tor/electrum

tor:/@[10:03] # service tor restart

tor:/@[10:04] # cat /var/db/tor/electrum/hostname

mdjus4gmduhofwcso57b3zl3ufoitguh2knitjco5cmgrokpreuxumad.onion

Oto nasz adres do połączenia. Sprawdźmy z lokalnej maszyny. Ale najpierw musimy dodać nasz klucz SSH:

wallet@electrum:/ % mkdir ~/ .ssh

wallet@electrum:/ % ee ~/ .ssh/authorized_keys

ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAG9Fk2Lqi4GQ8EXZrsH3EgSrVIQPQaAlS38MmJLBabihv9KHIDGXH7r018hxqLNNGbaJWO/wrWk7sG4T0yLHAbdQAFsMYof9kjoyuG56z0XZ8qaD/X/AjrhLMsIoBbUNj0AzxjKNlPJL4NbHsFwbmxGulKS0PdAD5oLcTQi/VnNdU7iFw== user@local

A z maszyny klienckiej z systemem Linux

user@local ~$ nano ~/ .ssh/config

#remote electrum wallet
Host remotebtc
        User wallet
        Port 22
        Hostname mdjus4gmduhofwcso57b3zl3ufoitguh2knitjco5cmgrokpreuxumad.onion
        ProxyCommand /bin/ncat --proxy localhost:9050 --proxy-type socks5 %h %p

Łączymy się (Aby to działało, potrzebny jest lokalny demon TOR, który słucha na porcie 9050)

user@local ~$ ssh remotebtc

Autentyczność hosta 'mdjus4gmduhofwcso57b3zl3ufoitguh2knitjco5cmgrokpreuxumad.onion ()' nie może być ustalona.
Odciśnięcie klucza ECDSA to SHA256:iW8FKjhVF4yyOZB1z4sBkzyvCM+evQ9cCL/EuWm0Du4.
Czy na pewno chcesz kontynuować połączenie (tak/nie/[odcisk])? tak
Ostrzeżenie: Na stałe dodano 'mdjus4gmduhofwcso57b3zl3ufoitguh2knitjco5cmgrokpreuxumad.onion' (ECDSA) do listy znanych hostów.
FreeBSD 12.1-RELEASE-p1 GENERIC
Aby zaoszczędzić miejsce na dysku w swoim katalogu domowym, skompresuj pliki, których rzadko używasz w "gzip filename".
 -- Dru 
wallet@electrum:~ % logout

Sukces!

Do pracy z płatnościami natychmiastowymi i mikro-płatnościami również potrzebna nam jest węzeł Lightning Network, to będzie nasze główne narzędzie do pracy z Bitcoinem. U *c-lightning, który zamierzamy wykorzystać jako demona, jest wtyczka Sparko, która stanowi pełnoprawny interfejs HTTP (REST) i umożliwia pracę zarówno z transakcjami off-chain, jak i on-chain. c-lightning do działania potrzebna jest bitcoind noda.

*istnieją różne implementacje protokołu Lightning Network w różnych językach programowania. Z tych, które przetestowaliśmy, c-lightning (napisany w C) okazał się najbardziej stabilny i efektywny pod względem zasobów.

# cbsd jsconstruct-tui

# cbsd jstart cln

# jexec cln

lightning:/@[10:23] # adduser

Nazwa użytkownika: lightning
...

lightning:/@[10:24] # pkg install git

lightning:/@[10:23] # su lightning

cd ~ && git clone https://github.com/ElementsProject/lightning

lightning@lightning:~ % exit

lightning:/@[10:30] # cd /home/lightning/lightning/

lightning:/home/lightning/lightning@[10:31] # pkg install autoconf automake gettext git gmp gmake libtool python python3 sqlite3 libsodium py36-mako bash bitcoin-utils

lightning:/home/lightning/lightning@[10:34] # ./configure && gmake && gmake install

W trakcie kompilacji i instalacji wszystkich potrzebnych składników, stwórzmy użytkownika RPC dla lightningd do bitcoind

# jexec bitcoind

bitcoind:/@[10:36] # ee /usr/local/etc/bitcoin.conf

rpcbind=192.168.0.1
rpcuser=test
rpcpassword=test
#zezwól tylko na c-lightning
rpcallowip=192.168.0.7/32

bitcoind:/@[10:39] # service bitcoind restart

Moje chaotyczne przełączanie między komórkami okazuje się nie być tak chaotyczne, jeśli oznaczyć narzędzie tmux, które pozwala na tworzenie wielu podsesji terminali w jednej sesji. Odpowiednik: screen

Bitcoin w klatce?

Dobra, nie chcemy ujawniać rzeczywistego IP naszej nodzie i chcemy prowadzić wszystkie operacje finansowe przez TOR. Dlatego potrzebujemy jeszcze jednego .onion.

# jexec tor

tor:/@[9:59] # ee /usr/local/etc/tor/torrc

HiddenServiceDir /var/db/tor/cln/
HiddenServicePort 9735 192.168.0.7:9735

tor:/@[10:01] # mkdir /var/db/tor/cln

tor:/@[10:01] # chown -R _tor:_tor /var/db/tor/cln

tor:/@[10:01] # chmod 700 /var/db/tor/cln

tor:/@[10:03] # service tor restart

tor:/@[10:04] # cat /var/db/tor/cln/hostname

en5wbkavnytti334jc5uzaudkansypfs6aguv6kech4hbzpcz2ove3yd.onion

teraz stwórzmy konfigurację dla c-lightning

lightning:/home/lightning/lightning@[10:31] # su lightning

lightning@lightning:~ % mkdir .lightning

lightning@lightning:~ % ee .lightning/config

alias=Moja-Węzeł-LN
bind-addr=192.168.0.7:9735
rgb=ff0000
announce-addr=en5wbkavnytti334jc5uzaudkansypfs6aguv6kech4hbzpcz2ove3yd.onion:9735
network=bitcoin
log-level=info
fee-base=0
fee-per-satoshi=1
proxy=192.168.0.2:9050
log-file=/home/lightning/.lightning/c-lightning.log
min-capacity-sat=200000

# wtyczka sparko
# https://github.com/fiatjaf/lightningd-gjson-rpc/tree/master/cmd/sparko

sparko-host=192.168.0.7
sparko-port=9737

sparko-tls-path=sparko-tls

#sparko-login=nazwa_użytkownika_portfela:hasło_portfela

#sparko-keys=masterkey;secretread:+listchannels,+listnodes;secretwrite:+invoice,+listinvoices,+delinvoice,+decodepay,+waitpay,+waitinvoice
sparko-keys=masterkey;secretread:+listchannels,+listnodes;ultrawrite:+invoice,+listinvoices,+delinvoice,+decodepay,+waitpay,+waitinvoice
# w przypadku powyższego przykładu logi inicjalizacji (zmieszane z logami lightningd) powinny pokazywać coś takiego jak

lightning@lightning:~ % mkdir .lightning/plugins

lightning@lightning:~ % cd .lightning/plugins/

lightning@lightning:~/.lightning/plugins:% fetch https://github.com/fiatjaf/sparko/releases/download/v0.2.1/sparko_full_freebsd_amd64

lightning@lightning:~/.lightning/plugins % mkdir ~/.lightning/sparko-tls

lightning@lightning:~/.lightning/sparko-tls % cd ~/.lightning/sparko-tls

lightning@lightning:~/.lightning/sparko-tls % openssl genrsa -out key.pem 2048

lightning@lightning:~/.lightning/sparko-tls % openssl req -new -x509 -sha256 -key key.pem -out cert.pem -days 3650

lightning@lightning:~/.lightning/plugins % chmod +x sparko_full_freebsd_amd64

lightning@lightning:~/.lightning/plugins % mv sparko_full_freebsd_amd64 sparko

lightning@lightning:~/.lightning/plugins % cd ~

należy również stworzyć plik konfiguracyjny dla bitcoin-cli, narzędzia do komunikacji z bitcoind

lightning@lightning:~ % mkdir .bitcoin

lightning@lightning:~ % ee .bitcoin/bitcoin.conf

rpcconnect=192.168.0.1
rpcuser=test
rpcpassword=test

sprawdzamy

lightning@lightning:~ % bitcoin-cli echo "test"

[
  "test"
]

uruchamiamy lightningd

lightning@lightning:~ % lightningd --daemon

Sam lightningd można zarządzać narzędziem lightning-cli, na przykład:

lightning-cli newaddr uzyskać adres dla nowej przychodzącej płatności

{
   "address": "bc1q2n2ffq3lplhme8jufcxahfrnfhruwjgx3c78pv",
   "bech32": "bc1q2n2ffq3lplhme8jufcxahfrnfhruwjgx3c78pv"
}

lightning-cli withdraw bc1jufcxahfrnfhruwjgx3cq2n2ffq3lplhme878pv all wysłać na adres wszystkie pieniądze z portfela (ze wszystkich adresów on-chain)

Poniżej znajdują się również komendy do operacji off-chain lightning-cli invoice, lightning-cli listinvoices, lightning-cli pay itd.

A do komunikacji z aplikacją mamy REST Api

curl -k https://192.168.0.7:9737/rpc -d '{"method": "pay", "params": ["lnbc..."]}' -H 'X-Access masterkey'

Podsumujmy

# jls

   JID  Adres IP      Nazwa hosta                      Ścieżka
     1  192.168.0.1     bitcoind.space.com            /zroot/jails/jails/bitcoind
     2  192.168.0.2     tor.space.com                 /zroot/jails/jails/tor
     3  192.168.0.3     nginx-rev.space.com           /zroot/jails/jails/nginx-rev
     4  192.168.0.4     paygw.space.com               /zroot/jails/jails/paygw
     5  192.168.0.5     webapp.my.domain              /zroot/jails/jails/webapp
     7  192.168.0.200   electrum.space.com            /zroot/jails/jails/electrum
     8  192.168.0.6     polipo.space.com              /zroot/jails/jails/polipo
     9  192.168.0.7     lightning.space.com           /zroot/jails/jails/cln

Bitcoin w klatce?

Mamy zestaw kontenerów, każdy z własnym poziomem dostępu zarówno do, jak i z lokalnej sieci.

# zfs list

NAZWA                    UŻYTO  DOSTĘPNY  ODNIESIENIE  PUNKT MONTAŻU
zroot                   279G  1.48T    88K  /zroot
zroot/ROOT             1.89G  1.48T    88K  none
zroot/ROOT/default     1.89G  17.6G  1.89G  /
zroot/home               88K  1.48T    88K  /home
zroot/jails             277G  1.48T   404M  /zroot/jails
zroot/jails/bitcoind    190G  1.48T   190G  /zroot/jails/jails-data/bitcoind-data
zroot/jails/cln         653M  1.48T   653M  /zroot/jails/jails-data/cln-data
zroot/jails/electrum    703M  1.48T   703M  /zroot/jails/jails-data/electrum-data
zroot/jails/nginx-rev   190M  1.48T   190M  /zroot/jails/jails-data/nginx-rev-data
zroot/jails/paygw      82.4G  1.48T  82.4G  /zroot/jails/jails-data/paygw-data
zroot/jails/polipo     57.6M  1.48T  57.6M  /zroot/jails/jails-data/polipo-data
zroot/jails/tor        81.5M  1.48T  81.5M  /zroot/jails/jails-data/tor-data
zroot/jails/webapp      360M  1.48T   360M  /zroot/jails/jails-data/webapp-data

Jak widać, bitcoind zajmuje całą przestrzeń 190 GB. A co jeśli potrzebujemy jeszcze jednego węzła do testów? W tym przypadku ZFS jest jak najbardziej przydatne. cbsd jclone old=bitcoind new=bitcoind-clone host_hostname=clonedbtc.space.com Można utworzyć zrzut i połączyć nową komórkę z tym zrzutem. Nowa komórka będzie miała całkowicie swoje własne przestrzeń, ale w systemie plików będą brane pod uwagę tylko różnice między bieżącym stanem a oryginałem (zaoszczędzimy co najmniej 190 GB).

Każda komórka to osobny zestaw danych ZFS, co jest niezwykle wygodne. ZFS pozwala również robić różne inne ciekawe rzeczy, takie jak przesyłanie zrzutów przez SSH. Nie będziemy tego opisywać, i tak już jest wystarczająco dużo informacji.

Warto również zauważyć konieczność zdalnego monitorowania hosta, w tym celu mamy Zabbix.

B — bezpieczeństwo

Jeśli chodzi o bezpieczeństwo, skupmy się na kluczowych zasadach w kontekście infrastruktury:

Prywatność — Standardowe narzędzia systemów podobnych do UNIX-a pozwalają na realizację tej zasady. Logicznnie dzielimy dostęp do każdego logicznie oddzielnego elementu systemu — komórki. Dostęp odbywa się za pomocą standardowej autoryzacji użytkowników przy użyciu kluczy prywatnych. Cała komunikacja między komórkami a docelowymi komórkami odbywa się w zaszyfrowanej formie. Dzięki szyfrowaniu dysków możemy nie martwić się o bezpieczeństwo danych podczas wymiany dysku lub migracji na inny serwer. Jedyny krytyczny dostęp to dostęp do systemu hosta, ponieważ taki dostęp zapewnia ogólnie dostęp do danych wewnątrz kontenerów.

Integralność — Realizacja tej zasady odbywa się na kilku różnych poziomach. Po pierwsze, ważne jest zauważyć, że w przypadku sprzętu serwerowego pamięci ECC oraz ZFS „z pudełka” dbają o integralność danych na poziomie bitów informacji. Natychmiastowe zrzuty pozwalają na wykonywanie kopii zapasowych w dowolnym momencie na bieżąco. Wygodne narzędzia do eksportu-importu komórek upraszczają replikację komórek.

Dostępność — To już opcjonalne. Zależy od stopnia twojej znanej reputacji i faktu posiadania wrogów. W naszym przykładzie zapewniliśmy dostępność portfela wyłącznie z sieci TOR. W razie potrzeby można w zaporze zablokować wszystko i umożliwić dostęp do serwera wyłącznie przez tuneli (TOR lub VPN to inna kwestia). Tak więc serwer zostanie odizolowany od świata zewnętrznego na tyle, na ile to możliwe, a na jego dostępność wpłynąć będziemy mogli tylko my sami.

Niemozliwość odmowy — To zależy od dalszej eksploatacji oraz przestrzegania odpowiednich polityk praw użytkowników, dostępu itd. Ale przy właściwym podejściu wszystkie działania użytkowników są audytowane, a dzięki rozwiązaniom kryptograficznym możliwe jest jednoznaczne zidentyfikowanie, kto i kiedy wykonał konkretne czynności.

Oczywiście opisana konfiguracja nie jest absolutnym przykładem, jak powinno to wyglądać zawsze, to raczej jeden z przykładów, jak to może być, zachowując bardzo elastyczne możliwości skalowania i dostosowywania.

A co z pełną wirtualizacją?

Pełna wirtualizacja za pomocą cbsd jest możliwa. przeczytać tutaj. Dodam tylko, że dla pracy bhyve należy włączyć niektóre parametry jądra.

# cat /etc/rc.conf

...
kld_list="vmm if_tap if_bridge nmdm"
...

# cat /boot/loader.conf

...
vmm_load="YES"
...

Więc jeśli pojawi się potrzeba założenia dockera, to podnosimy jakiś debian i do przodu!

Bitcoin w klatce?

I to wszystko.

Myślę, że to wszystko, czym chciałem się podzielić. Jeśli podobał Ci się artykuł, możesz przesłać mi bitcoiny — bc1qu7lhf45xw83ddll5mnzte6ahju8ktkeu6qhttc. Jeśli chcesz zobaczyć klatki w akcji i masz trochę bitcoinów, możesz wejść na mój pet-project.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster