Akses aman ke rumah pintar tanpa adanya IP publik (bagian 1)

pengantar


Sulit untuk memilih judul yang luas yang mencerminkan maknanya, jadi saya akan segera menggambarkan tugas yang saya tetapkan untuk diri saya sendiri.

Ada "rumah pintar". Dalam kasus saya, ini adalah server rumah tanpa kipas dengan ioBroker, meskipun ini tidak penting. Selain barang-barang rumah, saya ingin menghubungkan sensor ke luar (misalnya, pada ESP32 dari rumah kaca terpencil). Saya memutuskan untuk melakukan ini melalui mqtt. Akses ke antarmuka dari Internet.

Hal yang biasa. Namun ada nuansa:

  • Penyedia tidak memiliki cara untuk memberi saya alamat IP publik. Dan tidak ada penyedia lain.
  • Saya tidak suka mengikat ke layanan cloud tertentu. Layanan eksternal juga dapat ditutup (karena gbridge baru-baru ini mengirim pemberitahuan). Dan jika terjadi kegagalan, tidak jelas apa yang harus dilakukan. Saya lebih suka saya sendiri, yang dapat ditransfer, redone dengan sedikit darah jika sesuatu terjadi.
  • Keamanan itu penting. Bukan paranoia, tetapi menempatkan ioBroker di Internet, terutama mengingat ada beberapa layanan yang dipamerkan (flot ...). Tidak benar-benar.

Selanjutnya saya ingin menunjukkan bukan langsung hasilnya, tetapi prosesnya. Bagaimana kelanjutannya, bagaimana Daftar Keinginan diubah, keputusan berubah. Ada kemungkinan bahwa beberapa poin dapat diselesaikan dengan lebih benar / efisien (saya bukan administrator sistem, bukan pengembang). Atau mungkin seseorang tidak akan melangkah sejauh ini dan mengambil keuntungan dari solusi sementara yang, misalnya, saya tidak menemukan aman atau nyaman untuk diri saya sendiri. Sebenarnya, apa yang dijelaskan di bagian ini adalah opsi yang cukup berfungsi, tetapi bagi saya itu "perantara".

Alamat publik untuk mqtt


Di rumah, IP publik pada router tidak bersinar (saya tidak berbicara tentang diperbaiki, ini dapat diselesaikan melalui dyndns dan analog), yaitu, penyedia memberikan 10.x.x.x, tanpa opsi. Jadi, Anda perlu menyewa VPS kecil, dan membuat masalah melalui itu.

Cara termudah adalah dengan menelusuri ssh. Di server rumah (saya akan menyebutnya iob.xxx.xx) saya jalankan:

ssh -N -T -R pub.xxx.xx:1883:127.0.0.1:1883 a@iob.xxx.xx 

Menghubungkan ke port 1883 dari pub server eksternal.xxx.xx, pada kenyataannya Anda menemukan diri Anda di iob rumah Anda: 1883 dengan wadah mqtt (nyamuk) berjalan.

Tentu, ini perlu dimulai secara otomatis, koneksi dipulihkan setelah kegagalan. Karena itu, saya menggunakan autossh, mendesainnya sebagai layanan.

/etc/systemd/system/ssh_mqtt.service:

[Unit]
Description=SSH Tunnel mqtt
After=network.target

[Service]
Environment="AUTOSSH_GATETIME=0"
ExecStart=autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -NR pub.xxx.xx:1883:127.0.0.1:1883 -i /home/a/.ssh/id_rsa a@pub.xxx.xx

[Install]
WantedBy=multi-user.target

Semua jenis systemctl aktifkan / restart, dll. Saya tidak akan menjelaskan.

Sayangnya, meskipun autossh, saya dihantui oleh pembekuan konstan. Jadi saya memutuskan bahwa tidak perlu menghasilkan entitas dan menetap di ssh biasa:

/etc/systemd/system/ssh_mqtt.service:

[Unit]
Description=SSH Tunnel mqtt
After=network.target

[Service]
Restart=always
RestartSec=20
User=anri
ExecStart=/bin/ssh -N -T -R pub.xxx.xx:1883:127.0.0.1:1883 -i /home/a/.ssh/id_rsa a@pub.xxx.xx

[Install]
WantedBy=multi-user.target

Selanjutnya, omong-omong, ternyata penyedia ini sangat miring. Nah, atau tarif termurah untuk 45 rubel / bulan sehingga bengkok bekerja untuknya. Sesi hang secara berkala, bahkan ketika itu hanya terhubung melalui ssh (MobaXterm). Jadi pada akhirnya saya memesan sendiri VPS dari yang lain (55 rubel / bulan), dan masalah dengan pembekuan menghilang.

By the way, saya memilih untuk diri sendiri di mana mengambil VPS tidak hanya berdasarkan harga, tetapi juga memperhitungkan ping (10-20ms).

Secara umum, opsi ini cukup normal, terutama mengingat bahwa kemudian saya membuat koneksi internet secara eksklusif ke port 8883 melalui TLS. Itu Kata sandi untuk mosquitto dikirimkan dienkripsi.

Selanjutnya dibuat sertifikat klien wajib. Itu pertama, pada level TLS, Anda harus menunjukkan sertifikat klien, dan kemudian login dengan nama kata sandi yang ditentukan dalam nyamuk. Itu tidak mudah untuk sampai ke tahap pencarian kata sandi.
Oleh karena itu, pada awalnya saya menggunakan sertifikat server dari LetsEncrypt, kemudian, karena kebutuhan akan sertifikat klien, saya beralih ke penandatanganan diri.

Karena dalam proses saya juga bekerja pada perangkat lunak untuk ESP32, saya perhatikan (atau hanya berpikir, saya tidak ingat lagi) bahwa dengan masalah dengan koneksi VPN, baterai akan dikonsumsi jauh lebih cepat. Selama operasi normal, siklus: Bangun, berikan daya ke sensor, sambungkan ke WiFi, buat koneksi dengan server mqtt, baca bacaan sensor saat siap, transfer ke mqtt, matikan daya dari sensor, matikan tidur selama 10 menit.

Biasanya, siklus seperti itu membutuhkan waktu sekitar 4 detik. 1,5-2 detik - koneksi ke WiFi, satu detik tambahan karena transisi ke mqtt melalui TLS. Ini cocok untuk Anda selama 4 detik, semua sama, sensor membutuhkan waktu untuk bangun. Tetapi jika VPN turun (itu terlihat jelas ketika autossh jatuh), apa yang harus saya lakukan? Tentu saja, saya mengatur agar setelah 20 detik sistem akan tertidur. Tapi 20 detik, bukannya 4 sangat terlihat.

Secara umum, saya memutuskan bahwa lebih baik untuk menjaga server mqtt pada VPS eksternal. Sekarang semuanya bekerja seperti jam, saya tidak yakin apakah ini perlu. Tetapi saya tidak melihat adanya akal untuk memperbaikinya kembali.

Alamat Publik untuk Vis


Vis adalah sistem visualisasi populer di ioBroker. Anda tidak bisa repot-repot, dan konfigurasikan sendiri di https dan juga cukup meneruskan port. Selain itu, ia dapat meminta kata sandi di tingkat aplikasi.

Tapi itu tidak keren. Terutama mengingat bahwa untuk pekerjaan itu menghubungkan layanan tambahan. Katakanlah, saya menggambar grafik dalam flot, secara relatif, saya terhubung ke vis.xxx.xx : 8082 / vis / index.html, tetapi di dalamnya ada tautan ke grafik vis.xxx.xxx : 8082 / flot / index.html. Pada titik tertentu, ternyata ketika terhubung ke / vis, kata sandi diminta, dan antarmuka grafik dapat diakses tanpa kata sandi.

Pada beberapa saat itu umumnya aneh - saya diotorisasi pada vis, saya melihat grafik, tetapi di kanan bawah ada jendela "Tidak ada koneksi ke server". Menulis ulang untuk blok css ini untuk menyembunyikannya. Tetapi, segera setelah saya mulai menggunakan bingkai untuk beralih di antara grafik pada layar yang sama, ternyata tumpang tindih saya pada tampilan dalam bingkai tidak berhasil. (Ternyata nanti, seharusnya begitu). Saya mematikan otorisasi - semuanya baik-baik saja, tidak ada sumpah serapah.

Jadi saya memutuskan pada server eksternal yang sama untuk menaikkan nginx dalam mode proxy terbalik. Dan sudah membuat otorisasi di atasnya.

Dari peramban itu berfungsi. Tetapi aplikasi asli iobroker.vis dari Play Market tidak dapat masuk dengan cara ini. Dan saya ingin menggunakannya. Meskipun ini sebenarnya adalah browser di jendela, tetapi ia memiliki sejumlah fitur yang bagus. Katakanlah atur skala (93% dalam mode vertikal), dan gambar cocok. Di perangkat lain dengan resolusi layar yang berbeda, Anda cukup memilih koefisien, dan hanya itu. Dan di browser Anda perlu menyesuaikan setiap waktu ...

Oke, saya pikir. Saya akan menambahkan kode rumit di URL alih-alih kata sandi. Ketik vis.xxx.xx : 8082 / <long sequence> /vis/index.html. Seringkali trik semacam itu digunakan.

Hampir diterima. Tetapi dengan gangguan, penggalian menunjukkan bahwa aplikasi web ini tidak ditulis dengan benar. Banyak tautan di dalamnya bukan relatif, tetapi dari root.

Oke, saya menemukan beberapa tautan, saya menulis untuk mereka, kata mereka, jika perujuk berisi kode seperti itu, masih percaya, menulis ulang URL, dll. Tapi mereka perlahan terungkap. Jadi saya memutuskan bahwa ini bengkok, salah, dan pendekatan yang berbeda diperlukan.

VPN


Saya memutuskan untuk mengorbankan sedikit akses universalitas. Biarkan saya mendapatkan akses dari laptop saya, ponsel cerdas. Tetapi dari perangkat orang lain, dari warnet tidak diperlukan, saya akan mengaturnya. Kemudian Anda dapat menempatkan klien kecil yang akan menginstal VPN. Dan di dalamnya, SSL maupun otorisasi tidak diperlukan. Dan pada saat yang sama Anda tidak perlu mengulang tautannya.

Cara paling sederhana bagi saya adalah Zerotier. Untuk OS saya (Windows, Android, Linux) ada klien. Dan bahkan ada yang sudah jadi di buruh pelabuhan. Iya. Saya menjalankan semuanya di buruh pelabuhan, tentang fitur-fitur ini nanti.

Anda menginstal klien, masukkan kode unik untuk jaringan Anda, lalu konfirmasikan di antarmuka Web di my.zerotier.com , jika perlu, atur alamat statis dari jaringan pribadi pribadi Anda (a 10.20.30.0.0), dan hanya itu. Semua klien yang terhubung saling bertemu.

Satu-satunya hal yang saya harus berurusan dengan sedikit adalah "bagaimana menghubungkan ke server jauh dari perangkat di WiFi rumah Anda tanpa memulai klien." Yah, server rumah saya sudah menjadi klien, bahkan jika itu rute sendiri. Ternyata semuanya sederhana. Jaringan rumah 192.168.x.0 harus didaftarkan di my.zerotier.com di bagian Managed Routes, menetapkan sebagai gateway saya, tentu saja, ini adalah server rumah saya. Nah, di jaringan WiFi, konfigurasikan rute yang sesuai (pada router WiFi, statika 10.20.30.0 di server rumah).

Saat menghubungkan klien Zerotier, Anda dapat menentukan server DNS yang berbeda. Itu Saya menghubungkan klien, dan nama domain memutuskan tidak ke alamat publik, tetapi ke alamat pribadi, karena DNS sekarang menunjuk ke server rumah, di mana dnsmasq membuka untuk catatan IP individual dari jaringan pribadi Zerotier.

Bahkan Zerotier senang dengan pilihan rute yang efektif untuk koneksi. Jika saya mengaktifkan klien Zerotier di WiFi rumah, ping ke komputer rumah (alamat IP-nya dikeluarkan oleh Zerotier) adalah pasangan milidetik yang sama dengan tanpa klien (hanya melalui WiFi). Itu Menghubungkan ke cloud hanya pada saat pertama. Pertukaran lalu lintas selanjutnya dilakukan secara langsung, bukan melalui cloud. Jika Anda menginstal, misalnya, OpenVPN pada VPS, lalu lintas yang sama berjalan dari klien ke VPS, dan kemudian kembali ke jaringan WiFi yang sama ke server rumah.

Pada prinsipnya, bahkan ada chip untuk meletakkan server bulan Anda. Hampir dalam jaringan terputus dari Internet, semua ekonomi ini akan dikerahkan.

Apa hasilnya?


ESP32 mengirimkan datanya ke server mqtt yang digunakan pada VPS. Lebih dari TLS, sertifikat klien diperlukan.

VPN melalui Zerotier diinstal dengan server rumah. Sonoff rfBridge berkomunikasi dengan firmware Tasmota melalui server rumah ini dari mqtt ke VPS. Tidak ada cara untuk mengatur TLS dengan sertifikat klien, itu sebabnya MQTT yang biasa dikonfigurasi untuk 1883. Bagaimanapun, server rumah akan mengenkripsi lalu lintas ini menggunakan Zerotier.

Yah, saya terhubung ke vis dari jaringan rumah secara langsung, dan dari Internet dengan mengaktifkan klien Zerotier. Anda tidak dapat mematikannya sama sekali, ini juga berfungsi. Tetapi hanya kadang-kadang saya membutuhkan klien VPN lain (misalnya, pergi ke "Dilarang ILV"). Dua VPN pada satu smartphone tidak langsung menjadi teman, tetapi saya tidak mengerti.

Semuanya sangat sederhana. Tapi cacing itu menelan jiwa. Meskipun saya tidak memiliki reaktor nuklir, tetapi tiba-tiba? Ada kasus ketika mereka merusak TeamViewer (sebuah perusahaan, tidak secara khusus perangkat lunak klien), dan melalui mereka memperoleh akses ke banyak akun. Dan secara umum, saya menulis di awal bahwa saya mencintai semuanya milikku.
Jadi langkah selanjutnya, saya beralih dari Zerotier ke OpenVPN. Semuanya ada di tangan saya.

Satu-satunya "alien" adalah VPS penyedia. Yah, saya secara khusus meluncurkan segala sesuatu dalam wadah buruh pelabuhan untuk dapat langsung bergerak.
Jika saya tahu berapa banyak saya harus berurusan dengan OpenVPN, mungkin saya tidak akan melakukannya. Dalam keadilan - masalah utama justru karena wadah.

Kesimpulan


Dalam artikel selanjutnya saya akan berbicara tentang OpenVPN dan fitur konfigurasi dalam kondisi saya (wadah, perutean perangkat lain dari jaringan rumah). Akan ada lebih banyak konfigurasi, detail teknis, dan kesulitan. Tetapi segera bagian kedua tidak mulai menulis tanpa ini. Tidak akan jelas mengapa penyimpangan semacam itu diperlukan sama sekali.

Dan untuk berjaga-jaga, pertanyaan bagi mereka yang tahu: meskipun saya memiliki VPS dan yang kecil (RAM 512MB), digunakan kurang dari 1%. statistik buruh pelabuhan:

gambar

Dan saya mendapat ide untuk meluncurkan semuanya seperti sebuah wadah di beberapa Google Cloud Run, Amazon Fargate, atau yang serupa. Menyebarkan server dengan segala macam fail2ban melalui ansible bukan masalah. Instal Docker juga. Tetapi mengapa, jika Anda hanya membutuhkan sebagian kecil dari sumber dayanya?

Namun, menurut perhitungan saya, Fargate yang sama akan menelan biaya berkali-kali lipat.

Mungkin saya tidak mengerti sesuatu? Jadi akan menarik untuk memiliki wadah kecil murni untuk meneruskan rumah pelabuhan, dan bukan seluruh VPS. Tidak ada hal seperti itu?

All Articles