-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
1489 lines (1075 loc) · 180 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Geegeek'xo</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta property="og:type" content="website">
<meta property="og:title" content="Geegeek'xo">
<meta property="og:url" content="https://geegeek.github.io/index.html">
<meta property="og:site_name" content="Geegeek'xo">
<meta property="og:locale" content="en_US">
<meta property="article:author" content="geegeek">
<meta name="twitter:card" content="summary">
<link rel="alternate" href="/atom.xml" title="Geegeek'xo" type="application/atom+xml">
<link rel="shortcut icon" href="/favicon.png">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/fancybox/jquery.fancybox.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/fork-awesome.min.css">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-D9PQ5R85NW"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-D9PQ5R85NW');
</script>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
<div id="wrap">
<header id="header">
<div id="banner"></div>
<div id="header-outer" class="outer">
<div id="header-title" class="inner">
<h1 id="logo-wrap">
<a href="/" id="logo">Geegeek'xo</a>
</h1>
</div>
<div id="header-inner" class="inner">
<nav id="main-nav">
<a id="main-nav-toggle" class="nav-icon"><span class="fa fa-bars"></span></a>
<a class="main-nav-link" href="/">Home</a>
<a class="main-nav-link" href="/archives">Archives</a>
</nav>
<nav id="sub-nav">
<a class="nav-icon" href="/atom.xml" title="RSS Feed"><span class="fa fa-rss"></span></a>
<a class="nav-icon nav-search-btn" title="Search"><span class="fa fa-search"></span></a>
</nav>
<div id="search-form-wrap">
<form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit"></button><input type="hidden" name="sitesearch" value="https://geegeek.github.io"></form>
</div>
</div>
</div>
</header>
<div class="outer">
<section id="main">
<article id="post-Impostazione-dei-permessi-in-var-www-html-con-il-bit-SGID" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<div class="article-meta">
<a href="/2025/01/28/Impostazione-dei-permessi-in-var-www-html-con-il-bit-SGID/" class="article-date">
<time class="dt-published" datetime="2025-01-28T13:47:13.000Z" itemprop="datePublished">2025-01-28</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/SysAdmin/">SysAdmin</a>
</div>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="p-name article-title" href="/2025/01/28/Impostazione-dei-permessi-in-var-www-html-con-il-bit-SGID/">Impostazione dei permessi in /var/www/html con il bit SGID</a>
</h1>
</header>
<div class="e-content article-entry" itemprop="articleBody">
<h2 id="Introduzione"><a href="#Introduzione" class="headerlink" title="Introduzione"></a>Introduzione</h2><p>Quando più utenti devono collaborare su un progetto in un ambiente<br>Linux, nasce l’esigenza di gestire correttamente i permessi su file e<br>directory. Per evitare che i file creati da un singolo utente assumano<br>come <em>owner</em> e <em>group</em> il suo gruppo primario, possiamo sfruttare il bit<br>SGID (<em>Set Group ID</em>) sulle directory condivise.</p>
<p>In questo articolo vedremo come impostare il bit SGID solo sulle<br>directory — perché è pensato esclusivamente per gestire l’ereditarietà<br>del gruppo —, così da semplificare la collaborazione in una struttura<br>come <code>/var/www/html</code>.</p>
<h2 id="Il-problema"><a href="#Il-problema" class="headerlink" title="Il problema"></a>Il problema</h2><p>Supponiamo che un utente (es. <code>user1</code>) carichi o modifichi file via FTP<br>nella directory <code>/var/www/html</code>. Di default, ogni file nuovo assume come<br>proprietario <code>user1</code> e come gruppo il gruppo primario di <code>user1</code> (es.<br><code>user1</code> stesso). Se vogliamo che il gruppo di questi file sia invece<br><code>www-data</code> (tipico in ambiente web), dobbiamo configurare correttamente<br>i permessi e impostare il bit SGID sulle directory.</p>
<h2 id="Obiettivi"><a href="#Obiettivi" class="headerlink" title="Obiettivi"></a>Obiettivi</h2><ol>
<li>Far sì che tutte le directory sotto <code>/var/www/html</code> abbiano il<br>gruppo <code>www-data</code> e il bit SGID attivo, in modo che qualsiasi file<br>creato o caricato al loro interno eredi automaticamente il gruppo<br><code>www-data</code>.</li>
<li>Applicare permessi ragionevoli per directory (2775) e file (0644),<br>così da garantire che i membri del gruppo <code>www-data</code> possano<br>interagire correttamente con il contenuto, mantenendo un livello di<br>sicurezza adeguato.</li>
<li>Verificare che tutti i file e le directory appartengano<br>effettivamente al gruppo <code>www-data</code>.</li>
</ol>
<h2 id="Passo-1-Assegnare-proprieta-e-gruppo-a-var-www-html"><a href="#Passo-1-Assegnare-proprieta-e-gruppo-a-var-www-html" class="headerlink" title="Passo 1: Assegnare proprietà e gruppo a /var/www/html"></a>Passo 1: Assegnare proprietà e gruppo a /var/www/html</h2><p>Per prima cosa, se non l’hai già fatto, assegna ricorsivamente owner e<br>gruppo <code>www-data:www-data</code> a <code>/var/www/html</code>:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> <span class="built_in">chown</span> -R www-data:www-data /var/www/html</span><br></pre></td></tr></table></figure>
<p>Questo fa sì che l’utente e il gruppo su tutti i file e directory<br>all’interno di <code>/var/www/html</code> siano ora <code>www-data:www-data</code>.</p>
<h2 id="Passo-2-Impostare-i-permessi-sui-file-e-sulle-directory"><a href="#Passo-2-Impostare-i-permessi-sui-file-e-sulle-directory" class="headerlink" title="Passo 2: Impostare i permessi sui file e sulle directory"></a>Passo 2: Impostare i permessi sui file e sulle directory</h2><p>Distinguiamo due situazioni: <em>directory</em> e <em>file</em>.</p>
<ol>
<li><strong>Directory</strong>: vogliamo che abbiano i permessi 2775 (<em>rwxrwsr-x</em>).<ul>
<li>Il “2” all’inizio indica il bit SGID, così che tutti i nuovi<br>file/dir ereditino il gruppo della cartella madre (in questo<br>caso, <code>www-data</code>).</li>
<li>“775” permette al proprietario (<code>www-data</code>) e al gruppo di<br>leggere, scrivere ed entrare nella directory; gli “altri”<br>possono solo leggere ed entrare (<code>r-x</code>).</li>
</ul>
</li>
<li><strong>File</strong>: vogliamo che abbiano i permessi 0644 (<em>rw-r--r--</em>).<ul>
<li>In questo modo, il proprietario e il gruppo possono leggere e<br>scrivere, mentre gli altri possono solo leggere (nessuna<br>esecuzione di default).</li>
</ul>
</li>
</ol>
<p>Per applicare questi permessi ricorsivamente:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Imposta 2775 su tutte le directory</span></span><br><span class="line"><span class="built_in">sudo</span> find /var/www/html -<span class="built_in">type</span> d -<span class="built_in">exec</span> <span class="built_in">chmod</span> 2775 {} \;</span><br><span class="line"></span><br><span class="line"><span class="comment"># Imposta 0644 su tutti i file</span></span><br><span class="line"><span class="built_in">sudo</span> find /var/www/html -<span class="built_in">type</span> f -<span class="built_in">exec</span> <span class="built_in">chmod</span> 0644 {} \;</span><br></pre></td></tr></table></figure>
<p>In questo modo, ogni directory avrà:<br><code>rwxrwsr-x www-data www-data (2775)</code>, mentre ogni file avrà:<br><code>rw-r--r-- www-data www-data (0644)</code>.</p>
<h2 id="Passo-3-Verificare-che-il-bit-SGID-sia-applicato-solo-alle-directory"><a href="#Passo-3-Verificare-che-il-bit-SGID-sia-applicato-solo-alle-directory" class="headerlink" title="Passo 3: Verificare che il bit SGID sia applicato solo alle directory"></a>Passo 3: Verificare che il bit SGID sia applicato solo alle directory</h2><p>Il bit SGID va usato <em>solo</em> sulle directory, non sui file. Se vuoi<br>controllare che nelle directory sia attivo, puoi eseguire:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">ls</span> -ld /var/www/html</span><br></pre></td></tr></table></figure>
<p>Vedrai un output simile:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">drwxrwsr-x 5 www-data www-data 4096 Jan 22 12:34 /var/www/html</span><br></pre></td></tr></table></figure>
<p>dove la presenza di <code>s</code> nella sezione dei permessi del gruppo (<code>rws</code>)<br>indica che la directory ha il bit SGID attivo.</p>
<p>Se accidentalmente hai applicato SGID anche ai file, puoi rimuoverlo dai<br>soli file con:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> find /var/www/html -<span class="built_in">type</span> f -<span class="built_in">exec</span> <span class="built_in">chmod</span> g-s {} \;</span><br></pre></td></tr></table></figure>
<h2 id="Passo-4-Verificare-l’appartenenza-al-gruppo-www-data"><a href="#Passo-4-Verificare-l’appartenenza-al-gruppo-www-data" class="headerlink" title="Passo 4: Verificare l’appartenenza al gruppo www-data"></a>Passo 4: Verificare l’appartenenza al gruppo www-data</h2><p>Infine, se vuoi controllare che <em>tutti</em> i file e le directory<br>appartengano al gruppo <code>www-data</code> (e segnalare se qualcosa non va), puoi<br>usare un comando <code>find</code> dedicato:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> find /var/www/html -not -group www-data -<span class="built_in">exec</span> <span class="built_in">ls</span> -l {} \;</span><br></pre></td></tr></table></figure>
<p>Se non viene stampato nulla, significa che tutti gli elementi presenti<br>in <code>/var/www/html</code> hanno già il gruppo <code>www-data</code>.</p>
<h2 id="Conclusioni"><a href="#Conclusioni" class="headerlink" title="Conclusioni"></a>Conclusioni</h2><p>Configurare correttamente i permessi e il bit SGID in <code>/var/www/html</code> è<br>fondamentale per gestire un ambiente di sviluppo o produzione in cui più<br>utenti collaborano sui file. Impostando i permessi 2775 sulle directory<br>e 0644 sui file, e assicurandoti che il bit SGID sia attivo <em>solo</em> sulle<br>directory, potrai lavorare in modo coerente e ordinato, senza dover<br>correggere manualmente le impostazioni di proprietà ogni volta che<br>vengono caricati nuovi file.</p>
</div>
<footer class="article-footer">
<a data-url="https://geegeek.github.io/2025/01/28/Impostazione-dei-permessi-in-var-www-html-con-il-bit-SGID/" data-id="cm6gj9nub00002fj9h1wk4nkq" data-title="Impostazione dei permessi in /var/www/html con il bit SGID" class="article-share-link"><span class="fa fa-share">Share</span></a>
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/var-www-html/" rel="tag">/var/www/html</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Linux/" rel="tag">Linux</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Permessi/" rel="tag">Permessi</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/bit-SGID/" rel="tag">bit SGID</a></li></ul>
</footer>
</div>
</article>
<article id="post-Generazione-e-condivisione-di-password-online-tramite-github-Pages" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<div class="article-meta">
<a href="/2024/12/16/Generazione-e-condivisione-di-password-online-tramite-github-Pages/" class="article-date">
<time class="dt-published" datetime="2024-12-16T00:00:00.000Z" itemprop="datePublished">2024-12-16</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/Sicurezza-Informatica/">Sicurezza Informatica</a>►<a class="article-category-link" href="/categories/Sicurezza-Informatica/Strumenti-Online/">Strumenti Online</a>
</div>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="p-name article-title" href="/2024/12/16/Generazione-e-condivisione-di-password-online-tramite-github-Pages/">Generazione e condivisione di password online tramite github Pages</a>
</h1>
</header>
<div class="e-content article-entry" itemprop="articleBody">
<h1 id="Introduzione-alla-Sicurezza-delle-Password"><a href="#Introduzione-alla-Sicurezza-delle-Password" class="headerlink" title="Introduzione alla Sicurezza delle Password"></a>Introduzione alla Sicurezza delle Password</h1><p>Le password sono la prima linea di difesa per proteggere dati, account personali e risorse sensibili. Tuttavia, creare e ricordare password sufficientemente forti non è sempre semplice: è diffusa la cattiva abitudine di riutilizzare la stessa password per più servizi, oppure di crearne una troppo semplice e prevedibile.</p>
<p>Inoltre, quando si tratta di condividere queste credenziali con un collega, un collaboratore o un familiare, spesso vengono utilizzati canali non sicuri come email non cifrate o messaggistica istantanea. Questo tipo di condivisione espone a notevoli rischi, poiché chi intercetta il messaggio potrà potenzialmente utilizzare quella password. Per mitigare questi problemi, esistono strumenti online che semplificano sia la creazione di password complesse sia la loro condivisione in modo sicuro e temporaneo.</p>
<h2 id="Generatore-di-Password-Caratteristiche-e-Utilizzo"><a href="#Generatore-di-Password-Caratteristiche-e-Utilizzo" class="headerlink" title="Generatore di Password: Caratteristiche e Utilizzo"></a>Generatore di Password: Caratteristiche e Utilizzo</h2><p>Il primo strumento è un <strong>generatore di password</strong> disponibile su GitHub Pages. Questo servizio permette di creare password casuali di diversa complessità. L’utente può personalizzare i parametri in base alle proprie necessità: lunghezza, utilizzo di caratteri speciali, maiuscole, minuscole e numeri.</p>
<ul>
<li><p><strong>Accesso allo Strumento</strong>:<br>Il generatore è disponibile qui: <a href="https://geegeek.github.io/password/index.html">https://geegeek.github.io/password/index.html</a><br>Una volta aperta la pagina, è possibile selezionare i parametri desiderati (ad esempio, una lunghezza compresa tra 12 e 16 caratteri, includendo numeri e simboli) e generare una password complessa.</p>
</li>
<li><p><strong>Esempio di Generazione</strong>:<br>Supponiamo di voler creare una password robusta di 16 caratteri, contenente lettere maiuscole, minuscole, numeri e simboli. Lo strumento restituirà una stringa casuale, ad esempio: </p>
<blockquote>
<blockquote>
<blockquote>
<p>XyZ!9mLpQ3r#1BdT </p>
</blockquote>
</blockquote>
</blockquote>
<p>Questa password, lunga e complessa, non è facile da indovinare e rappresenta un buon punto di partenza per garantire un livello di sicurezza medio.</p>
</li>
</ul>
<h2 id="One-Time-Password-Link-Condivisione-Sicura-e-Temporanea"><a href="#One-Time-Password-Link-Condivisione-Sicura-e-Temporanea" class="headerlink" title="One-Time Password Link: Condivisione Sicura e Temporanea"></a>One-Time Password Link: Condivisione Sicura e Temporanea</h2><p>Il secondo strumento consente di condividere in modo sicuro la password generata, creando un link monouso attraverso cui il destinatario potrà visualizzare la password una sola volta. Questo meccanismo riduce la probabilità che la password resti esposta a lungo in chiaro su un canale di comunicazione insicuro.</p>
<ul>
<li><p><strong>Accesso allo Strumento</strong>:<br>Il servizio one-time si trova qui: <a href="https://geegeek.github.io/password/1timepassword/index.html">https://geegeek.github.io/password/1timepassword/index.html</a></p>
</li>
<li><p><strong>Funzionamento</strong>:<br>Una volta ottenuta la password dal generatore, è possibile trasferirla allo strumento 1timepassword, che creerà un link univoco. Chi riceve questo link potrà visualizzare la password una sola volta; dopodiché, il link non sarà più valido. In questo modo si riducono notevolmente i rischi legati alla condivisione diretta del testo.</p>
</li>
<li><p><strong>Vantaggi della Condivisione Monouso</strong>: </p>
<ul>
<li>Evita di scrivere la password in chiaro su un canale di comunicazione. </li>
<li>La password non rimane disponibile online a lungo. </li>
<li>Una volta visualizzata, il link si “autodistrugge”, minimizzando l’esposizione.</li>
</ul>
</li>
</ul>
<h2 id="Integrazione-tra-i-due-Strumenti"><a href="#Integrazione-tra-i-due-Strumenti" class="headerlink" title="Integrazione tra i due Strumenti"></a>Integrazione tra i due Strumenti</h2><p>Una delle caratteristiche più interessanti di questi due servizi è la possibilità di integrarli tra loro. Il flusso può essere riassunto così:</p>
<ol>
<li>L’utente genera una password complessa con il primo strumento.</li>
<li>La password viene automaticamente passata allo strumento one-time password.</li>
<li>Si genera un link monouso, che l’utente può inviare al destinatario.</li>
</ol>
<p>Questo processo semplifica notevolmente la fase di condivisione. Non si deve copiare e incollare manualmente la password, riducendo errori e garantendo un flusso più lineare.</p>
<ul>
<li><p><strong>Esempio Pratico Passo Passo</strong>: </p>
<ol>
<li>Aprire <a href="https://geegeek.github.io/password/index.html">https://geegeek.github.io/password/index.html</a> </li>
<li>Generare una password con i parametri desiderati. </li>
<li>Cliccare sull’opzione per passare la password generata allo strumento one-time (se disponibile nell’interfaccia). </li>
<li>Aprire <a href="https://geegeek.github.io/password/1timepassword/index.html">https://geegeek.github.io/password/1timepassword/index.html</a> </li>
<li>Ottenere il link generato. </li>
<li>Condividere il link con il destinatario in modo sicuro.</li>
</ol>
</li>
<li><p><strong>Benefici dell’Integrazione</strong>: </p>
<ul>
<li>Facilità d’uso: non serve copiare e incollare. </li>
<li>Riduzione degli errori: la password passa direttamente dall’uno all’altro strumento. </li>
<li>Maggiore sicurezza: il link monouso limita l’esposizione della password.</li>
</ul>
</li>
</ul>
<h2 id="Aspetti-Tecnici-e-Codice-di-Base"><a href="#Aspetti-Tecnici-e-Codice-di-Base" class="headerlink" title="Aspetti Tecnici e Codice di Base"></a>Aspetti Tecnici e Codice di Base</h2><p>Entrambi gli strumenti sono hostati su GitHub Pages, una soluzione semplice per pubblicare siti statici. Le pagine si basano su HTML, CSS e JavaScript. Il codice di integrazione può essere facilmente analizzato e modificato a seconda delle esigenze.</p>
<ul>
<li><p><strong>Struttura dei File</strong>:<br>In genere, si hanno file HTML per la struttura della pagina, CSS per il layout e JS per la logica di generazione e passaggio delle password.<br>Uno schema generico potrebbe essere: </p>
<blockquote>
<blockquote>
<blockquote>
<p>index.html<br>├── style.css<br>└── script.js </p>
</blockquote>
</blockquote>
</blockquote>
</li>
<li><p><strong>Esempio di Integrazione del Codice</strong>:<br>Nella pagina del generatore di password (index.html) potrebbe esserci un codice JavaScript che, una volta generata la password, effettua un redirect o invoca un endpoint della pagina del one-time password.</p>
<p>Ad esempio: </p>
<blockquote>
<blockquote>
<blockquote>
<p>// Generazione della password<br>const password = generatePassword({ length: 16, symbols: true, numbers: true });<br>// Invio la password allo strumento one-time attraverso un parametro GET<br>const oneTimeUrl = “<a href="https://geegeek.github.io/password/1timepassword/index.html?pwd=">https://geegeek.github.io/password/1timepassword/index.html?pwd=</a>“ + encodeURIComponent(password);<br>console.log(“Visita questo link per la password monouso:”, oneTimeUrl);</p>
</blockquote>
</blockquote>
</blockquote>
<p>Questa è una semplice illustrazione. In pratica, il codice effettivo potrebbe essere più complesso.</p>
</li>
<li><p><strong>Configurazioni di Base Consigliate</strong>: </p>
<ol>
<li><strong>Lunghezza della password</strong>: almeno 12 caratteri. </li>
<li><strong>Caratteri inclusi</strong>: lettere minuscole, maiuscole, numeri e simboli. </li>
<li><strong>HTTPS obbligatorio</strong>: assicurarsi che la condivisione del link avvenga sempre tramite protocollo HTTPS. </li>
<li><strong>Aggiornamenti periodici</strong>: mantenere il codice aggiornato per includere eventuali fix di sicurezza.</li>
</ol>
</li>
</ul>
<h2 id="Buone-Pratiche-di-Sicurezza"><a href="#Buone-Pratiche-di-Sicurezza" class="headerlink" title="Buone Pratiche di Sicurezza"></a>Buone Pratiche di Sicurezza</h2><p>L’impiego di strumenti come questi non elimina la necessità di attenersi a buone pratiche di sicurezza:</p>
<ul>
<li><strong>Non riutilizzare le password</strong>: Non utilizzare la stessa password per più account. </li>
<li><strong>Cambiare periodicamente le password</strong>: Aggiornare le credenziali ogni tre-sei mesi. </li>
<li><strong>Utilizzare password manager riconosciuti</strong>: Se necessario, impiegare un password manager affidabile. </li>
<li><strong>Verificare la provenienza dei link</strong>: Non cliccare su link sospetti. Il link monouso per la password deve provenire da una fonte fidata.</li>
</ul>
<h2 id="Conclusioni-e-Sviluppi-Futuri"><a href="#Conclusioni-e-Sviluppi-Futuri" class="headerlink" title="Conclusioni e Sviluppi Futuri"></a>Conclusioni e Sviluppi Futuri</h2><p>Gli strumenti presentati offrono una soluzione semplice per migliorare la sicurezza nella creazione e condivisione delle password. La combinazione tra un generatore affidabile e un servizio di link monouso riduce al minimo i rischi legati alla divulgazione non autorizzata delle credenziali.</p>
<p>Guardando al futuro, sarebbe possibile integrare ulteriormente queste funzionalità con API di messaggistica sicura o aggiungere restrizioni temporali più raffinate (ad esempio, il link è valido per un numero limitato di minuti).</p>
<p>In conclusione, l’approccio è semplice, non richiede particolari competenze tecniche e può migliorare la vita di chiunque debba gestire e condividere password in modo più sicuro e consapevole.</p>
<p>NOTA BENE:<br>Pur essendo un metodo pratico e immediato per condividere informazioni sensibili senza l’ausilio di infrastrutture complesse, è importante considerare attentamente le implicazioni di sicurezza e le limitazioni di questo approccio, tenendo presente che – anche se crittografata – la password viene comunque trasmessa nell’URL, con i relativi rischi.</p>
</div>
<footer class="article-footer">
<a data-url="https://geegeek.github.io/2024/12/16/Generazione-e-condivisione-di-password-online-tramite-github-Pages/" data-id="cm5wmibd3000935j9amdqcoqa" data-title="Generazione e condivisione di password online tramite github Pages" class="article-share-link"><span class="fa fa-share">Share</span></a>
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/one-time-password/" rel="tag">one-time password</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/password-generator/" rel="tag">password generator</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/sicurezza/" rel="tag">sicurezza</a></li></ul>
</footer>
</div>
</article>
<article id="post-Come-identificare-e-gestire-i-file-che-occupano-troppo-spazio-su-disco-da-linea-di-comando" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<div class="article-meta">
<a href="/2024/12/12/Come-identificare-e-gestire-i-file-che-occupano-troppo-spazio-su-disco-da-linea-di-comando/" class="article-date">
<time class="dt-published" datetime="2024-12-12T17:32:08.000Z" itemprop="datePublished">2024-12-12</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/Amministrazione-di-Sistema/">Amministrazione di Sistema</a>►<a class="article-category-link" href="/categories/Amministrazione-di-Sistema/Linux/">Linux</a>
</div>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="p-name article-title" href="/2024/12/12/Come-identificare-e-gestire-i-file-che-occupano-troppo-spazio-su-disco-da-linea-di-comando/">Come identificare e gestire i file che occupano troppo spazio su disco da linea di comando</a>
</h1>
</header>
<div class="e-content article-entry" itemprop="articleBody">
<p>Quando lo spazio su disco inizia a ridursi, diventa importante individuare quali directory o file consumano grandi quantità di spazio di archiviazione. Disporre dei giusti comandi da riga di comando è essenziale per una manutenzione quotidiana del proprio HomeLab, permettendo di affrontare con calma ed efficienza situazioni potenzialmente critiche.</p>
<p>In questo articolo vedremo alcuni comandi utili per analizzare lo spazio su disco su sistemi Linux. Verranno illustrate anche alcune strategie per liberare spazio, mantenendo un livello di sicurezza medio-alto e operando in modo ragionevole. Nessuna pratica eccessivamente rischiosa verrà proposta, e suggeriremo sempre di operare con la massima cautela.</p>
<hr>
<h3 id="Panoramica-sullo-spazio-su-disco"><a href="#Panoramica-sullo-spazio-su-disco" class="headerlink" title="Panoramica sullo spazio su disco"></a>Panoramica sullo spazio su disco</h3><p>Prima di tutto, è utile avere una panoramica generale dell’utilizzo delle partizioni:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">df</span> -h</span><br></pre></td></tr></table></figure>
<p>L’opzione <code>-h</code> (human-readable) converte i valori in unità facilmente leggibili (KB, MB, GB). Da questo output, potrai vedere subito se una partizione è vicina al limite della sua capacità.</p>
<hr>
<h3 id="Identificare-le-directory-piu-grandi"><a href="#Identificare-le-directory-piu-grandi" class="headerlink" title="Identificare le directory più grandi"></a>Identificare le directory più grandi</h3><p>Quando individui una partizione critica (ad esempio <code>/opt/NOME_DIRECTORY</code>), puoi analizzare la struttura delle directory al suo interno:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">du</span> -h /opt/NOME_DIRECTORY --max-depth=1 2>/dev/null | <span class="built_in">sort</span> -hr | <span class="built_in">head</span> -n 10</span><br></pre></td></tr></table></figure>
<ul>
<li><code>du -h</code>: mostra la dimensione delle directory in modo leggibile </li>
<li><code>--max-depth=1</code>: limita la profondità dell’analisi a un solo livello </li>
<li><code>sort -hr</code>: ordina i risultati dal più grande al più piccolo </li>
<li><code>head -n 10</code>: mostra le prime 10 linee</li>
<li>L’opzione <code>2>/dev/null</code> viene utilizzata per ignorare i messaggi di errore relativi a directory non accessibili, semplificando l’analisi dell’output. In alcuni contesti potresti ometterla, se preferisci vedere quali percorsi non possono essere letti.</li>
</ul>
<p>Se individui una sottodirectory di grandi dimensioni, puoi approfondire ulteriormente nello stesso modo:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">du</span> -h /opt/NOME_DIRECTORY/GRANDE_CARTELLA_1 --max-depth=1 2>/dev/null | <span class="built_in">sort</span> -hr | <span class="built_in">head</span> -n 10</span><br></pre></td></tr></table></figure>
<p>Queste analisi a imbuto ti consentono di scendere gradualmente fino ai singoli file più ingombranti.</p>
<hr>
<h3 id="Cercare-file-di-grandi-dimensioni"><a href="#Cercare-file-di-grandi-dimensioni" class="headerlink" title="Cercare file di grandi dimensioni"></a>Cercare file di grandi dimensioni</h3><p>Se desideri individuare direttamente i file più pesanti, puoi utilizzare:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">find / -<span class="built_in">type</span> f -size +100M 2>/dev/null | <span class="built_in">head</span> -n 20</span><br></pre></td></tr></table></figure>
<ul>
<li><code>find /</code>: inizia la ricerca dalla radice </li>
<li><code>-type f</code>: cerca solo file </li>
<li><code>-size +100M</code>: limita la ricerca ai file maggiori di 100MB </li>
<li><code>2>/dev/null</code>: sopprime i messaggi di errore su directory non accessibili </li>
<li><code>head -n 20</code>: mostra solo i primi 20 risultati</li>
</ul>
<p>In questo modo otterrai una rapida lista dei maggiori responsabili del consumo di spazio.</p>
<hr>
<h3 id="Strumenti-interattivi-ncdu"><a href="#Strumenti-interattivi-ncdu" class="headerlink" title="Strumenti interattivi: ncdu"></a>Strumenti interattivi: ncdu</h3><p>Se puoi installare nuovi tool nel tuo HomeLab, <code>ncdu</code> è uno strumento interattivo molto utile:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">apt update</span><br><span class="line">apt install ncdu</span><br></pre></td></tr></table></figure>
<p>Una volta installato, puoi eseguirlo con:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ncdu /home/utente</span><br></pre></td></tr></table></figure>
<p><code>ncdu</code> fornisce un’interfaccia testuale per navigare tra le directory, visualizzarne le dimensioni e, se necessario, eliminare i file direttamente dall’interfaccia. Eccone simile esempio:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">ncdu 1.19 ~ Use the arrow keys to navigate, press ? <span class="keyword">for</span> <span class="built_in">help</span></span><br><span class="line">--- /home/utente ---------------------------------------------------------------------------</span><br><span class="line"> 120.0 MiB [########################] /progettoX</span><br><span class="line"> 60.5 MiB [############ ] /.local</span><br><span class="line"> 32.2 MiB [##### ] /.cache</span><br><span class="line"> 15.0 MiB [## ] /documenti</span><br><span class="line"> 5.0 MiB [ ] /.ssh</span><br><span class="line"> 2.0 MiB [ ] config_backup.tar.gz</span><br><span class="line"> 1.0 MiB [ ] notes.txt</span><br><span class="line"> 40.0 KiB [ ] .bash_history</span><br><span class="line"> 4.0 KiB [ ] .bashrc</span><br><span class="line"> 4.0 KiB [ ] .profile</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<hr>
<h3 id="Altri-comandi-utili"><a href="#Altri-comandi-utili" class="headerlink" title="Altri comandi utili"></a>Altri comandi utili</h3><ol>
<li><p><strong><code>du -sh *</code> nella directory corrente</strong><br>Mostra la dimensione di ogni directory e file nel percorso corrente, per una rapida panoramica.</p>
</li>
<li><p><strong><code>lsof +aL1 /NOME_MONTAGGIO</code></strong><br>A volte lo spazio è occupato da file già cancellati ma ancora aperti da qualche processo. Questo comando mostra i file aperti con link count zero, evidenziando i casi in cui è sufficiente terminare il processo per liberare spazio.</p>
</li>
<li><p><strong><code>df -i</code></strong><br>Se sospetti che non sia lo spazio ad esaurirsi, ma gli inode, <code>df -i</code> ti mostrerà quanti inode sono utilizzati. Gli inode sono strutture dati utilizzate per gestire informazioni sui file, come metadati, permessi e puntatori al contenuto; un eccesso di file molto piccoli può saturare il numero di inode disponibili.</p>
</li>
</ol>
<hr>
<h3 id="Caso-reale-avviso-da-un-servizio-di-monitoraggio-Nagios"><a href="#Caso-reale-avviso-da-un-servizio-di-monitoraggio-Nagios" class="headerlink" title="Caso reale: avviso da un servizio di monitoraggio (Nagios)"></a>Caso reale: avviso da un servizio di monitoraggio (Nagios)</h3><p>Vediamo ora un esempio pratico di come questi comandi possano risultare utili, sia in un’infrastruttura aziendale complessa che in un semplice HomeLab. È una pratica diffusa configurare uno o più servizi di monitoraggio, come Nagios o Zabbix, per tenere sotto controllo lo stato delle macchine. Questi strumenti possono raccogliere dati in modi diversi:</p>
<ul>
<li><p><strong>Con agent</strong>: Il sistema monitorato esegue un software agente (come <code>NRPE</code> per Nagios o l’agente nativo di Zabbix) che invia periodicamente informazioni sullo stato delle risorse (utilizzo CPU, RAM, spazio disco, servizi attivi) al server di monitoraggio.</p>
</li>
<li><p><strong>Senza agent (agentless)</strong>: Il server di monitoraggio interroga direttamente i sistemi target usando protocolli standard come SNMP, WMI (per macchine Windows) o SSH. In questo caso non è necessario installare nulla sul sistema da controllare, riducendo così la complessità dell’infrastruttura.</p>
</li>
</ul>
<p>Nel mio HomeLab, ad esempio, ho ricevuto un avviso da Nagios, che segnalava una situazione critica su un host generico (<code>NOME_HOST</code>). Ecco un esempio del messaggio:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">***** Nagios Monitor XI Alert *****</span><br><span class="line"></span><br><span class="line">Notification Type: PROBLEM</span><br><span class="line"></span><br><span class="line">Service: Check linux disk usage </span><br><span class="line">Host: NOME_HOST </span><br><span class="line">Address: NOME_INDIRIZZO_IP </span><br><span class="line">State: CRITICAL</span><br><span class="line"></span><br><span class="line">Date/Time: NOME_DATA_ORA</span><br><span class="line"></span><br><span class="line">Additional Info:</span><br><span class="line"></span><br><span class="line">CRITICAL. DISK STATS: / al 90%, /opt/NOME_DIRECTORY al 100%.</span><br></pre></td></tr></table></figure>
<p>Questa notifica mi ha spinto a utilizzare i comandi sopra descritti, individuando con facilità i file e le directory più ingombranti. Ciò mi ha permesso di liberare spazio in modo mirato e sicuro, riducendo l’impatto sull’ambiente e prevenendo potenziali downtime.</p>
<hr>
<p><strong>In conclusione</strong>, utilizzare comandi come <code>df</code>, <code>du</code>, <code>find</code>, o tool interattivi come <code>ncdu</code>, ti permette di individuare rapidamente le aree problematiche del tuo spazio su disco, mantenendo un approccio umile, controllato e sicuro nel tempo. Queste pratiche diventano fondamentali per evitare situazioni di emergenza e mantenere il tuo HomeLab ottimizzato e funzionale.</p>
</div>
<footer class="article-footer">
<a data-url="https://geegeek.github.io/2024/12/12/Come-identificare-e-gestire-i-file-che-occupano-troppo-spazio-su-disco-da-linea-di-comando/" data-id="cm5wmibcl000235j97csic3hh" data-title="Come identificare e gestire i file che occupano troppo spazio su disco da linea di comando" class="article-share-link"><span class="fa fa-share">Share</span></a>
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/HomeLab/" rel="tag">HomeLab</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Linux/" rel="tag">Linux</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Nagios/" rel="tag">Nagios</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/manutenzione/" rel="tag">manutenzione</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/spazio-disco/" rel="tag">spazio disco</a></li></ul>
</footer>
</div>
</article>
<article id="post-Esempi-Pratici-di-Expect-sulla-CLI-Linux-Accesso-Remoto-e-Gestione-Password" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<div class="article-meta">
<a href="/2024/12/10/Esempi-Pratici-di-Expect-sulla-CLI-Linux-Accesso-Remoto-e-Gestione-Password/" class="article-date">
<time class="dt-published" datetime="2024-12-10T00:00:00.000Z" itemprop="datePublished">2024-12-10</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="p-name article-title" href="/2024/12/10/Esempi-Pratici-di-Expect-sulla-CLI-Linux-Accesso-Remoto-e-Gestione-Password/">Esempi Pratici di Expect sulla CLI Linux: Accesso Remoto e Gestione Password</a>
</h1>
</header>
<div class="e-content article-entry" itemprop="articleBody">
<h2 id="Introduzione"><a href="#Introduzione" class="headerlink" title="Introduzione"></a>Introduzione</h2><p>In ambiente Linux/Unix, l’automazione di compiti ripetitivi e l’interazione non presidiata con programmi che richiedono input da tastiera sono attività frequenti. L’utilizzo di <strong>Expect</strong> offre una soluzione semplice e versatile: questo strumento consente di definire in anticipo le risposte a richieste interattive, evitando la necessità di sviluppare interi script in linguaggi più complessi come Python o PHP.</p>
<p>Garantire un buon livello di sicurezza nell’automazione è fondamentale. Gli esempi forniti di seguito mantengono un approccio prudente: utilizzeremo account non privilegiati o con le autorizzazioni minime necessarie, eviteremo l’uso diretto dell’utente root e ci assicureremo di non memorizzare password in chiaro su file non protetti. L’obiettivo è automatizzare task comuni in modo sicuro e affidabile.</p>
<h2 id="Cosa-e-Expect"><a href="#Cosa-e-Expect" class="headerlink" title="Cosa è Expect?"></a>Cosa è Expect?</h2><p>Expect è un programma che permette di “dialogare” con altri programmi interattivi secondo uno script. In altre parole, con Expect si può:</p>
<ul>
<li>Avviare un programma interattivo (come <code>ssh</code> o <code>passwd</code>)</li>
<li>Attendere determinate risposte, prompt o messaggi</li>
<li>Inviare input predefiniti in risposta a tali messaggi</li>
</ul>
<p>Il linguaggio di scripting di Expect si basa su Tcl, un linguaggio interpretato, semplice ma potente, che fornisce strutture di controllo (if, for), definizione di procedure, manipolazione di stringhe e molto altro. Questa combinazione consente di creare script di automazione flessibili, capaci di gestire condizioni variabili e flussi logici complessi.</p>
<h2 id="Quando-e-Perche-Usare-Expect"><a href="#Quando-e-Perche-Usare-Expect" class="headerlink" title="Quando e Perché Usare Expect?"></a>Quando e Perché Usare Expect?</h2><p>Expect è utile in qualsiasi scenario in cui si necessiti di fornire risposte previste a input richiesti da un programma. Ad esempio:</p>
<ul>
<li>Accesso remoto a sistemi via SSH senza dover inserire la password manualmente, utile quando si devono eseguire comandi su più server.</li>
<li>Gestione automatizzata delle password, ad esempio per aggiornare le credenziali di un account locale su più macchine.</li>
<li>Automazione di procedure interne a sistemi legacy o applicazioni non modernizzate.</li>
</ul>
<p>Rispetto ad altre soluzioni come l’uso di librerie Python o di Ansible, Expect può risultare più semplice e immediato, specialmente per piccole automazioni quotidiane o integrazioni rapide all’interno di script Bash esistenti.</p>
<h2 id="Installazione-e-Uso-di-Base"><a href="#Installazione-e-Uso-di-Base" class="headerlink" title="Installazione e Uso di Base"></a>Installazione e Uso di Base</h2><p>Prima di tutto, verificare che Expect sia installato:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">which</span> expect</span><br><span class="line">``` </span><br><span class="line">Se non installato, utilizzare il gestore pacchetti della distribuzione per aggiungerlo. Ad esempio su Debian/Ubuntu:</span><br><span class="line">```bash</span><br><span class="line"><span class="built_in">sudo</span> apt-get update && <span class="built_in">sudo</span> apt-get install expect</span><br></pre></td></tr></table></figure>
<p>Per eseguire uno script Expect:</p>
<ul>
<li>Creare il file con estensione <code>.exp</code></li>
<li>Assicurarsi che abbia i permessi di esecuzione</li>
<li>Lanciare lo script con:<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">expect -f nome_script.exp</span><br></pre></td></tr></table></figure></li>
</ul>
<p>È anche possibile rendere lo script eseguibile e utilizzare il <strong>shebang</strong>:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/usr/bin/expect -f</span></span><br></pre></td></tr></table></figure>
<p>In questo modo si potrà lanciare lo script direttamente, come un normale comando.</p>
<p>Per maggiori dettagli sulle opzioni, consultare la pagina man di Expect:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">man expect</span><br></pre></td></tr></table></figure>
<h2 id="Esempio-1-Connessione-SSH-e-Comando-Remoto"><a href="#Esempio-1-Connessione-SSH-e-Comando-Remoto" class="headerlink" title="Esempio 1: Connessione SSH e Comando Remoto"></a>Esempio 1: Connessione SSH e Comando Remoto</h2><p>Un caso tipico è l’accesso a un server remoto via SSH per eseguire un comando specifico. Immaginiamo di dover connetterci a un server senza inserire manualmente la password e lanciare un singolo comando remoto.</p>
<p><strong>Prerequisiti di sicurezza:</strong></p>
<ul>
<li>Assicurarsi di utilizzare chiavi SSH protette da passphrase se possibile, oppure conservare la password in modo sicuro (ad esempio in un file con permessi limitati).</li>
<li>Non utilizzare l’utente root, ma un account non privilegiato.</li>
</ul>
<h3 id="Script-di-Esempio"><a href="#Script-di-Esempio" class="headerlink" title="Script di Esempio"></a>Script di Esempio</h3><p>Creare un file <code>ssh_command.exp</code> con il seguente contenuto:</p>
<figure class="highlight tcl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/expect -f</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Verifica dei parametri: username, password, server, porta, comando</span></span><br><span class="line"><span class="keyword">if</span> {[<span class="keyword">llength</span> <span class="variable">$argv</span>] != <span class="number">5</span>} {</span><br><span class="line"> <span class="keyword">puts</span> <span class="string">"Uso: ./ssh_command.exp <username> <password> <server> <porta> <comando>"</span></span><br><span class="line"> <span class="keyword">exit</span> <span class="number">1</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">set</span> username [<span class="keyword">lindex</span> <span class="variable">$argv</span> <span class="number">0</span>]</span><br><span class="line"><span class="keyword">set</span> password [<span class="keyword">lindex</span> <span class="variable">$argv</span> <span class="number">1</span>]</span><br><span class="line"><span class="keyword">set</span> server [<span class="keyword">lindex</span> <span class="variable">$argv</span> <span class="number">2</span>]</span><br><span class="line"><span class="keyword">set</span> port [<span class="keyword">lindex</span> <span class="variable">$argv</span> <span class="number">3</span>]</span><br><span class="line"><span class="keyword">set</span> command [<span class="keyword">lindex</span> <span class="variable">$argv</span> <span class="number">4</span>]</span><br><span class="line"></span><br><span class="line"><span class="keyword">set</span> timeout <span class="number">60</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Avvio della sessione SSH</span></span><br><span class="line">spawn ssh -p <span class="variable">$port</span> <span class="variable">$username</span>@<span class="variable">$server</span> <span class="variable">$command</span></span><br><span class="line">expect <span class="string">"?assword:"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Invio della password</span></span><br><span class="line">send <span class="string">"$password\r"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Attendo la fine dell’esecuzione del comando</span></span><br><span class="line">expect <span class="keyword">eof</span></span><br></pre></td></tr></table></figure>
<p>Rendere lo script eseguibile:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">chmod</span> +x ssh_command.exp</span><br></pre></td></tr></table></figure>
<p>Eseguire lo script:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./ssh_command.exp utente password server.example.com 22 <span class="string">"ls -l"</span></span><br></pre></td></tr></table></figure>
<p>Lo script effettuerà la connessione, inserirà la password per voi ed eseguirà il comando <code>ls -l</code> sul server remoto.</p>
<h2 id="Esempio-2-Cambio-Password-Utente-con-Expect"><a href="#Esempio-2-Cambio-Password-Utente-con-Expect" class="headerlink" title="Esempio 2: Cambio Password Utente con Expect"></a>Esempio 2: Cambio Password Utente con Expect</h2><p>Supponiamo di voler aggiornare la password di un account locale. L’uso di Expect consente di automatizzare questo processo senza inserire manualmente la password all’interno del prompt di <code>passwd</code>.</p>
<p><strong>Nota di Sicurezza:</strong> </p>
<ul>
<li>Non utilizzare l’utente root. Utilizzare un account con i permessi minimi sufficienti a modificare la password desiderata. In un contesto reale, valutare attentamente le autorizzazioni del proprio ambiente.</li>
<li>Evitare di lasciare password in chiaro su file non sicuri. Eventualmente usare variabili d’ambiente protette, o gestori di segreti sicuri.</li>
</ul>
<h3 id="Script-di-Esempio-1"><a href="#Script-di-Esempio-1" class="headerlink" title="Script di Esempio"></a>Script di Esempio</h3><p>Creare il file <code>passwd_change.exp</code>:</p>
<figure class="highlight tcl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/expect -f</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> {[<span class="keyword">llength</span> <span class="variable">$argv</span>] != <span class="number">2</span>} {</span><br><span class="line"> <span class="keyword">puts</span> <span class="string">"Uso: ./passwd_change.exp <username> <nuova_password>"</span></span><br><span class="line"> <span class="keyword">exit</span> <span class="number">1</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">set</span> username [<span class="keyword">lindex</span> <span class="variable">$argv</span> <span class="number">0</span>]</span><br><span class="line"><span class="keyword">set</span> newpass [<span class="keyword">lindex</span> <span class="variable">$argv</span> <span class="number">1</span>]</span><br><span class="line"></span><br><span class="line"><span class="keyword">set</span> timeout <span class="number">20</span></span><br><span class="line"></span><br><span class="line">spawn passwd <span class="variable">$username</span></span><br><span class="line">expect <span class="string">"assword:"</span></span><br><span class="line">send <span class="string">"$newpass\r"</span></span><br><span class="line">expect <span class="string">"assword:"</span></span><br><span class="line">send <span class="string">"$newpass\r"</span></span><br><span class="line">expect <span class="keyword">eof</span></span><br></pre></td></tr></table></figure>
<p>Rendere lo script eseguibile:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">chmod</span> +x passwd_change.exp</span><br></pre></td></tr></table></figure>
<p>Eseguire lo script per cambiare la password:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./passwd_change.exp utente locale_nuova_password</span><br></pre></td></tr></table></figure>
<h2 id="Integrazione-con-Script-Bash"><a href="#Integrazione-con-Script-Bash" class="headerlink" title="Integrazione con Script Bash"></a>Integrazione con Script Bash</h2><p>Expect può essere facilmente integrato all’interno di script Bash più ampi. Ad esempio, potremmo avere uno script Bash che esegue aggiornamenti periodici su un server e successivamente richiama Expect per eseguire comandi remoti in modo automatizzato.</p>
<p>Esempio di snippet Bash che chiama lo script di connessione SSH:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Aggiornamenti o altre operazioni di contesto qui...</span></span><br><span class="line"><span class="comment"># Variabili definite all’interno dello script Bash</span></span><br><span class="line">USERNAME=<span class="string">"utente"</span></span><br><span class="line">PASSWORD=<span class="string">"mypass"</span></span><br><span class="line">SERVER=<span class="string">"server.example.com"</span></span><br><span class="line">PORT=22</span><br><span class="line">COMMAND=<span class="string">"uptime"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Richiama lo script Expect</span></span><br><span class="line">./ssh_command.exp <span class="string">"<span class="variable">$USERNAME</span>"</span> <span class="string">"<span class="variable">$PASSWORD</span>"</span> <span class="string">"<span class="variable">$SERVER</span>"</span> <span class="string">"<span class="variable">$PORT</span>"</span> <span class="string">"<span class="variable">$COMMAND</span>"</span></span><br></pre></td></tr></table></figure>
<p>In questo modo è possibile combinare logica Bash, controllo di flussi, cicli e condizioni con la capacità interattiva di Expect.</p>
<h2 id="Considerazioni-Finali"><a href="#Considerazioni-Finali" class="headerlink" title="Considerazioni Finali"></a>Considerazioni Finali</h2><p>Gli esempi presentati mostrano come Expect possa semplificare l’automazione di operazioni comuni:</p>
<ul>
<li>Connettersi a un server remoto e dare comandi in autonomia.</li>
<li>Aggiornare la password di un utente locale senza interazioni manuali.</li>
</ul>
<p>L’uso di Expect rimane flessibile: può essere applicato a numerosi altri scenari, dalla configurazione di dispositivi di rete all’interazione con applicazioni legacy. L’approccio basato su Tcl rende Expect potente e adattabile. È consigliabile esplorare la documentazione completa per scoprire funzionalità avanzate come la gestione dei timeout, l’uso di pattern più complessi e l’integrazione con altri strumenti.</p>
<h2 id="Riferimenti-e-Risorse"><a href="#Riferimenti-e-Risorse" class="headerlink" title="Riferimenti e Risorse"></a>Riferimenti e Risorse</h2><ul>
<li><p>Pagina man di Expect:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">man expect</span><br></pre></td></tr></table></figure></li>
<li><p>Documentazione Tcl:<br><a target="_blank" rel="noopener" href="https://www.tcl.tk/">https://www.tcl.tk/</a></p>
</li>
<li><p>Esempi aggiuntivi e progetti open source su GitHub e altri repository di script per l’automazione, dove potete trovare soluzioni reali e suggerimenti pratici.</p>
</li>
</ul>
<p>In definitiva, l’obiettivo è mantenere un equilibrio tra automazione e sicurezza, adottando pratiche prudenziali come l’uso di account non privilegiati, la protezione delle credenziali e la verifica costante degli script prima di metterli in produzione.</p>
</div>
<footer class="article-footer">
<a data-url="https://geegeek.github.io/2024/12/10/Esempi-Pratici-di-Expect-sulla-CLI-Linux-Accesso-Remoto-e-Gestione-Password/" data-id="cm5wmibd2000735j9b8cl7wfb" data-title="Esempi Pratici di Expect sulla CLI Linux: Accesso Remoto e Gestione Password" class="article-share-link"><span class="fa fa-share">Share</span></a>
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/automazione/" rel="tag">automazione</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/linux/" rel="tag">linux</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/networking/" rel="tag">networking</a></li></ul>
</footer>
</div>
</article>
<article id="post-Automatizzare-la-configurazione-differenziata-dell-accesso-SSH-con-Ansible" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<div class="article-meta">
<a href="/2024/12/09/Automatizzare-la-configurazione-differenziata-dell-accesso-SSH-con-Ansible/" class="article-date">
<time class="dt-published" datetime="2024-12-09T00:00:00.000Z" itemprop="datePublished">2024-12-09</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="p-name article-title" href="/2024/12/09/Automatizzare-la-configurazione-differenziata-dell-accesso-SSH-con-Ansible/">Automatizzare la configurazione differenziata dell'accesso SSH con Ansible</a>
</h1>
</header>
<div class="e-content article-entry" itemprop="articleBody">
<h2 id="Introduzione"><a href="#Introduzione" class="headerlink" title="Introduzione"></a>Introduzione</h2><p>Nel precedente articolo abbiamo esplorato come implementare una configurazione SSH modulare su un server Ubuntu/Debian, differenziando i metodi di accesso a seconda della provenienza (interna o esterna), degli utenti e dei metodi di autenticazione. Abbiamo separato la configurazione in file multipli all’interno di <code>sshd_config.d</code>, applicando politiche restrittive per l’accesso esterno e più permissive per la rete interna, oltre a integrare fail2ban, firewall (<code>ufw</code>) e il port forwarding su porte alte per aumentare la sicurezza.</p>
<p>In questo nuovo articolo ci concentreremo sull’automazione dello stesso identico approccio utilizzando <strong>Ansible</strong>, uno strumento di automazione dell’infrastruttura che ci consentirà di distribuire e mantenere le medesime configurazioni su uno o più server in modo semplice, ripetibile e privo di errori umani. L’uso di Ansible garantisce che le configurazioni siano idempotenti: eseguendo il playbook più volte otterremo sempre lo stato desiderato, senza dover ritoccare manualmente i file o rischiare inconsistenze.</p>
<p>Obiettivi principali:</p>
<ul>
<li>Automatizzare l’installazione e configurazione di OpenSSH Server.</li>
<li>Gestire i file di configurazione (<code>/etc/ssh/sshd_config</code> e <code>/etc/ssh/sshd_config.d/*.conf</code>) tramite Ansible.</li>
<li>Impostare regole <code>ufw</code> e configurazione base di <code>fail2ban</code>.</li>
<li>Creare utenti, impostare chiavi SSH, differenziare l’accesso da interno ed esterno.</li>
<li>Integrare il port forwarding su porte alte e mostrare come questa configurazione rimane coerente nel tempo.</li>
<li>Mantenere la stessa logica del precedente articolo, ma ora tramite playbook Ansible.</li>
</ul>
<h2 id="Prerequisiti"><a href="#Prerequisiti" class="headerlink" title="Prerequisiti"></a>Prerequisiti</h2><ul>
<li>Un controller Ansible (ad esempio un sistema locale con Ansible installato).</li>
<li>Connessione SSH al server o ai server bersaglio, con utente avente privilegi <code>sudo</code>.</li>
<li>Chiavi SSH già installate sul controller per l’utente amministrativo che si collegherà al target in modo da non dover usare password negli <code>ansible-playbook</code>.</li>
<li>Un server Ubuntu/Debian di destinazione, aggiornato e con un utente sudo.</li>
<li>Configurazione base di rete, con la possibilità di configurare il router per il port forwarding (come descritto nel precedente articolo).</li>
<li>Conoscenza base di Ansible e della struttura di un playbook.</li>
</ul>
<h2 id="Struttura-del-Progetto-Ansible"><a href="#Struttura-del-Progetto-Ansible" class="headerlink" title="Struttura del Progetto Ansible"></a>Struttura del Progetto Ansible</h2><p>Possiamo organizzare il nostro progetto con la seguente struttura:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">ansible/</span><br><span class="line">├─ inventory.ini</span><br><span class="line">├─ playbook.yaml</span><br><span class="line">└─ roles/</span><br><span class="line"> └─ ssh_config/</span><br><span class="line"> ├─ tasks/</span><br><span class="line"> │ ├─ main.yaml</span><br><span class="line"> │ ├─ firewall.yaml</span><br><span class="line"> │ ├─ fail2ban.yaml</span><br><span class="line"> │ ├─ sshd.yaml</span><br><span class="line"> │ └─ users.yaml</span><br><span class="line"> ├─ templates/</span><br><span class="line"> │ ├─ sshd_config.j2</span><br><span class="line"> │ ├─ 00-internal.conf.j2</span><br><span class="line"> │ └─ 01-external.conf.j2</span><br><span class="line"> └─ files/</span><br><span class="line"> └─ authorized_keys_deploy</span><br></pre></td></tr></table></figure>
<ul>
<li><strong>inventory.ini:</strong> Contiene l’inventario dei nostri host da configurare.</li>
<li><strong>playbook.yaml:</strong> Il file principale che esegue il ruolo <code>ssh_config</code>.</li>
<li><strong>roles/ssh_config/tasks/:</strong> Directory con i task divisi per argomento (firewall, fail2ban, sshd, utenti).</li>
<li><strong>roles/ssh_config/templates/:</strong> I template Jinja2 per generare i file di configurazione.</li>
<li><strong>roles/ssh_config/files/:</strong> Eventuali file statici come chiavi autorizzate.</li>
</ul>
<p>È possibile variare la struttura secondo le preferenze, ma questa offre una buona separazione delle responsabilità.</p>
<h2 id="L’inventario-di-Ansible"><a href="#L’inventario-di-Ansible" class="headerlink" title="L’inventario di Ansible"></a>L’inventario di Ansible</h2><p>Nel file <code>inventory.ini</code> definiremo i server target:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[ssh_servers]</span><br><span class="line">myserver ansible_host=aa.bb.cc.dd ansible_user=mio_utente</span><br></pre></td></tr></table></figure>
<p>Sostituite <code>aa.bb.cc.dd</code> con l’IP pubblico del server o un dominio che lo punti. L’<code>ansible_user</code> è l’utente sudo locale creato in precedenza.</p>
<h2 id="Variabili-e-Considerazioni"><a href="#Variabili-e-Considerazioni" class="headerlink" title="Variabili e Considerazioni"></a>Variabili e Considerazioni</h2><p>Nelle variabili potremmo definire:</p>
<ul>
<li>La rete interna da cui consentire l’accesso con password (es. <code>192.168.0.0/24</code>).</li>
<li>L’IP esterno o range ammesso all’accesso via chiave.</li>
<li>L’utente dedicato all’accesso esterno (es. <code>deploy</code>).</li>
</ul>
<p>Queste variabili possono essere definite nel <code>playbook.yaml</code> o in <code>group_vars/ssh_servers.yaml</code> per maggiore scalabilità.</p>
<p>Esempio di variabili (in <code>playbook.yaml</code> o in un file <code>vars.yaml</code>):</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">vars:</span></span><br><span class="line"> <span class="attr">internal_network:</span> <span class="string">"192.168.0.0/24"</span></span><br><span class="line"> <span class="attr">external_ip:</span> <span class="string">"aa.bb.cc.dd"</span></span><br><span class="line"> <span class="attr">external_user:</span> <span class="string">"deploy"</span></span><br><span class="line"> <span class="attr">ssh_port:</span> <span class="number">22</span></span><br><span class="line"> <span class="attr">external_port:</span> <span class="number">22222</span> <span class="comment"># porta esterna sul router</span></span><br></pre></td></tr></table></figure>
<h2 id="Il-Playbook-Principale-playbook-yaml"><a href="#Il-Playbook-Principale-playbook-yaml" class="headerlink" title="Il Playbook Principale: playbook.yaml"></a>Il Playbook Principale: <code>playbook.yaml</code></h2><p>Questo playbook eseguirà il ruolo <code>ssh_config</code> sui server del gruppo <code>ssh_servers</code>:</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Configure</span> <span class="string">SSH</span> <span class="string">access</span> <span class="string">via</span> <span class="string">Ansible</span></span><br><span class="line"> <span class="attr">hosts:</span> <span class="string">ssh_servers</span></span><br><span class="line"> <span class="attr">become:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">vars:</span></span><br><span class="line"> <span class="attr">internal_network:</span> <span class="string">"192.168.0.0/24"</span></span><br><span class="line"> <span class="attr">external_ip:</span> <span class="string">"aa.bb.cc.dd"</span></span><br><span class="line"> <span class="attr">external_user:</span> <span class="string">"deploy"</span></span><br><span class="line"> <span class="attr">ssh_port:</span> <span class="number">22</span></span><br><span class="line"> <span class="attr">external_port:</span> <span class="number">22222</span></span><br><span class="line"> <span class="attr">roles:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">ssh_config</span></span><br></pre></td></tr></table></figure>
<h2 id="Il-Ruolo-ssh-config"><a href="#Il-Ruolo-ssh-config" class="headerlink" title="Il Ruolo ssh_config"></a>Il Ruolo <code>ssh_config</code></h2><p>Il ruolo si occupa di:</p>
<ol>
<li><p><strong>Installare e configurare OpenSSH Server:</strong> </p>
<ul>
<li>Assicurarsi che <code>openssh-server</code> sia installato.</li>
<li>Copiare i template di configurazione in <code>/etc/ssh/</code>.</li>
<li>Riavviare il demone <code>sshd</code>.</li>
</ul>
</li>
<li><p><strong>Configurare il firewall (ufw):</strong> </p>
<ul>
<li>Consentire la porta 22 (interna) se serve.</li>
<li>Limitare l’accesso esterno eventualmente per IP specifici.</li>
<li>Gestire le regole per consentire l’accesso dalla LAN e limitare l’esterno.</li>
</ul>
</li>
<li><p><strong>Configurare fail2ban:</strong> </p>
<ul>
<li>Installare fail2ban se non presente.</li>
<li>Copiare una configurazione base.</li>
<li>Riavviare fail2ban.</li>
</ul>
</li>
<li><p><strong>Creare utenti, chiavi SSH, assegnare i privilegi:</strong> </p>
<ul>
<li>Creare l’utente <code>deploy</code> se non esiste.</li>
<li>Aggiungere la chiave pubblica a <code>~deploy/.ssh/authorized_keys</code>.</li>
<li>Configurare l’utente amministrativo.</li>
</ul>
</li>
<li><p><strong>Template per <code>sshd_config</code> e <code>sshd_config.d/*.conf</code>:</strong> </p>
<ul>
<li><code>sshd_config.j2</code> contenente configurazioni generali.</li>
<li><code>00-internal.conf.j2</code> e <code>01-external.conf.j2</code> per differenziare gli accessi.</li>
</ul>
</li>
</ol>
<h3 id="Esempio-di-tasks-main-yaml"><a href="#Esempio-di-tasks-main-yaml" class="headerlink" title="Esempio di tasks/main.yaml"></a>Esempio di <code>tasks/main.yaml</code></h3><p>Questo file includerà gli altri file di task:</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Include</span> <span class="string">firewall</span> <span class="string">tasks</span></span><br><span class="line"> <span class="attr">include_tasks:</span> <span class="string">firewall.yaml</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Include</span> <span class="string">fail2ban</span> <span class="string">tasks</span></span><br><span class="line"> <span class="attr">include_tasks:</span> <span class="string">fail2ban.yaml</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Include</span> <span class="string">sshd</span> <span class="string">tasks</span></span><br><span class="line"> <span class="attr">include_tasks:</span> <span class="string">sshd.yaml</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Include</span> <span class="string">users</span> <span class="string">tasks</span></span><br><span class="line"> <span class="attr">include_tasks:</span> <span class="string">users.yaml</span></span><br></pre></td></tr></table></figure>
<h3 id="Esempio-di-tasks-firewall-yaml"><a href="#Esempio-di-tasks-firewall-yaml" class="headerlink" title="Esempio di tasks/firewall.yaml"></a>Esempio di <code>tasks/firewall.yaml</code></h3><p>Questa sezione:</p>
<ul>
<li>Installa <code>ufw</code> se non presente.</li>
<li>Resetta le regole, permette SSH interno, limita l’esterno all’IP definito.</li>
</ul>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Ensure</span> <span class="string">ufw</span> <span class="string">is</span> <span class="string">installed</span></span><br><span class="line"> <span class="attr">apt:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">ufw</span></span><br><span class="line"> <span class="attr">state:</span> <span class="string">present</span></span><br><span class="line"> <span class="attr">update_cache:</span> <span class="literal">yes</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Reset</span> <span class="string">ufw</span> <span class="string">rules</span></span><br><span class="line"> <span class="attr">command:</span> <span class="string">ufw</span> <span class="string">--force</span> <span class="string">reset</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Allow</span> <span class="string">internal</span> <span class="string">SSH</span> <span class="string">access</span></span><br><span class="line"> <span class="attr">ufw:</span></span><br><span class="line"> <span class="attr">rule:</span> <span class="string">allow</span></span><br><span class="line"> <span class="attr">port:</span> <span class="string">"<span class="template-variable">{{ ssh_port }}</span>"</span></span><br><span class="line"> <span class="attr">proto:</span> <span class="string">tcp</span></span><br><span class="line"> <span class="attr">source:</span> <span class="string">"<span class="template-variable">{{ internal_network }}</span>"</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Allow</span> <span class="string">external</span> <span class="string">SSH</span> <span class="string">from</span> <span class="string">specified</span> <span class="string">IP</span> <span class="string">only</span></span><br><span class="line"> <span class="attr">ufw:</span></span><br><span class="line"> <span class="attr">rule:</span> <span class="string">allow</span></span><br><span class="line"> <span class="attr">port:</span> <span class="string">"<span class="template-variable">{{ ssh_port }}</span>"</span></span><br><span class="line"> <span class="attr">proto:</span> <span class="string">tcp</span></span><br><span class="line"> <span class="attr">source:</span> <span class="string">"<span class="template-variable">{{ external_ip }}</span>"</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Enable</span> <span class="string">ufw</span></span><br><span class="line"> <span class="attr">ufw:</span></span><br><span class="line"> <span class="attr">state:</span> <span class="string">enabled</span></span><br></pre></td></tr></table></figure>
<p>Qui apriamo la 22 solo per la rete interna e per l’IP specificato per l’esterno. Questo riflette la logica precedente: da esterno accede solo un IP e uno specifico utente.</p>
<h3 id="Esempio-di-tasks-fail2ban-yaml"><a href="#Esempio-di-tasks-fail2ban-yaml" class="headerlink" title="Esempio di tasks/fail2ban.yaml"></a>Esempio di <code>tasks/fail2ban.yaml</code></h3><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Ensure</span> <span class="string">fail2ban</span> <span class="string">is</span> <span class="string">installed</span></span><br><span class="line"> <span class="attr">apt:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">fail2ban</span></span><br><span class="line"> <span class="attr">state:</span> <span class="string">present</span></span><br><span class="line"> <span class="attr">update_cache:</span> <span class="literal">yes</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Configure</span> <span class="string">fail2ban</span></span><br><span class="line"> <span class="attr">copy:</span></span><br><span class="line"> <span class="attr">dest:</span> <span class="string">/etc/fail2ban/jail.local</span></span><br><span class="line"> <span class="attr">content:</span> <span class="string">|</span></span><br><span class="line"><span class="string"> [sshd]</span></span><br><span class="line"><span class="string"> enabled = true</span></span><br><span class="line"><span class="string"> port = {{ ssh_port }}</span></span><br><span class="line"><span class="string"> filter = sshd</span></span><br><span class="line"><span class="string"> logpath = /var/log/auth.log</span></span><br><span class="line"><span class="string"> maxretry = 5</span></span><br><span class="line"><span class="string"> findtime = 600</span></span><br><span class="line"><span class="string"> bantime = 3600</span></span><br><span class="line"><span class="string"> ignoreip = 127.0.0.1/8 {{ internal_network }}</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Restart</span> <span class="string">fail2ban</span></span><br><span class="line"> <span class="attr">service:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">fail2ban</span></span><br><span class="line"> <span class="attr">state:</span> <span class="string">restarted</span></span><br></pre></td></tr></table></figure>
<p>Abbiamo ignorato il range interno in modo che la LAN non venga bannata da tentativi multipli.</p>
<h3 id="Esempio-di-tasks-users-yaml"><a href="#Esempio-di-tasks-users-yaml" class="headerlink" title="Esempio di tasks/users.yaml"></a>Esempio di <code>tasks/users.yaml</code></h3><p>Creiamo l’utente <code>deploy</code> e aggiungiamo la sua chiave pubblica. Presumiamo di avere una chiave pubblica pronta nel ruolo (in <code>files/authorized_keys_deploy</code>):</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Ensure</span> <span class="string">deploy</span> <span class="string">user</span> <span class="string">exists</span></span><br><span class="line"> <span class="attr">user:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">"<span class="template-variable">{{ external_user }}</span>"</span></span><br><span class="line"> <span class="attr">shell:</span> <span class="string">/bin/bash</span></span><br><span class="line"> <span class="attr">create_home:</span> <span class="literal">yes</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Ensure</span> <span class="string">.ssh</span> <span class="string">directory</span> <span class="string">exists</span></span><br><span class="line"> <span class="attr">file:</span></span><br><span class="line"> <span class="attr">path:</span> <span class="string">"/home/<span class="template-variable">{{ external_user }}</span>/.ssh"</span></span><br><span class="line"> <span class="attr">state:</span> <span class="string">directory</span></span><br><span class="line"> <span class="attr">owner:</span> <span class="string">"<span class="template-variable">{{ external_user }}</span>"</span></span><br><span class="line"> <span class="attr">group:</span> <span class="string">"<span class="template-variable">{{ external_user }}</span>"</span></span><br><span class="line"> <span class="attr">mode:</span> <span class="string">'0700'</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Deploy</span> <span class="string">the</span> <span class="string">authorized_keys</span> <span class="string">file</span></span><br><span class="line"> <span class="attr">copy:</span></span><br><span class="line"> <span class="attr">src:</span> <span class="string">authorized_keys_deploy</span></span><br><span class="line"> <span class="attr">dest:</span> <span class="string">"/home/<span class="template-variable">{{ external_user }}</span>/.ssh/authorized_keys"</span></span><br><span class="line"> <span class="attr">owner:</span> <span class="string">"<span class="template-variable">{{ external_user }}</span>"</span></span><br><span class="line"> <span class="attr">group:</span> <span class="string">"<span class="template-variable">{{ external_user }}</span>"</span></span><br><span class="line"> <span class="attr">mode:</span> <span class="string">'0600'</span></span><br></pre></td></tr></table></figure>
<h3 id="Esempio-di-tasks-sshd-yaml"><a href="#Esempio-di-tasks-sshd-yaml" class="headerlink" title="Esempio di tasks/sshd.yaml"></a>Esempio di <code>tasks/sshd.yaml</code></h3><p>Qui gestiamo i file di configurazione <code>sshd_config</code> e <code>sshd_config.d</code> tramite template:</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Ensure</span> <span class="string">openssh-server</span> <span class="string">is</span> <span class="string">installed</span></span><br><span class="line"> <span class="attr">apt:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">openssh-server</span></span><br><span class="line"> <span class="attr">state:</span> <span class="string">present</span></span><br><span class="line"> <span class="attr">update_cache:</span> <span class="literal">yes</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Backup</span> <span class="string">original</span> <span class="string">sshd_config</span> <span class="string">if</span> <span class="string">present</span></span><br><span class="line"> <span class="attr">copy:</span></span><br><span class="line"> <span class="attr">src:</span> <span class="string">/etc/ssh/sshd_config</span></span><br><span class="line"> <span class="attr">dest:</span> <span class="string">/etc/ssh/sshd_config.bak</span></span><br><span class="line"> <span class="attr">remote_src:</span> <span class="literal">yes</span></span><br><span class="line"> <span class="attr">force:</span> <span class="literal">no</span></span><br><span class="line"> <span class="attr">when:</span> <span class="string">ansible_stat.exists</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">vars:</span></span><br><span class="line"> <span class="attr">ansible_stat:</span> <span class="string">"<span class="template-variable">{{ lookup('ansible.builtin.stat', '/etc/ssh/sshd_config') }}</span>"</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Deploy</span> <span class="string">main</span> <span class="string">sshd_config</span></span><br><span class="line"> <span class="attr">template:</span></span><br><span class="line"> <span class="attr">src:</span> <span class="string">sshd_config.j2</span></span><br><span class="line"> <span class="attr">dest:</span> <span class="string">/etc/ssh/sshd_config</span></span><br><span class="line"> <span class="attr">owner:</span> <span class="string">root</span></span><br><span class="line"> <span class="attr">group:</span> <span class="string">root</span></span><br><span class="line"> <span class="attr">mode:</span> <span class="string">'0644'</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Ensure</span> <span class="string">sshd_config.d</span> <span class="string">directory</span> <span class="string">exists</span></span><br><span class="line"> <span class="attr">file:</span></span><br><span class="line"> <span class="attr">path:</span> <span class="string">/etc/ssh/sshd_config.d</span></span><br><span class="line"> <span class="attr">state:</span> <span class="string">directory</span></span><br><span class="line"> <span class="attr">mode:</span> <span class="string">'0755'</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Deploy</span> <span class="number">00</span><span class="string">-internal.conf</span></span><br><span class="line"> <span class="attr">template:</span></span><br><span class="line"> <span class="attr">src:</span> <span class="number">00</span><span class="string">-internal.conf.j2</span></span><br><span class="line"> <span class="attr">dest:</span> <span class="string">/etc/ssh/sshd_config.d/00-internal.conf</span></span><br><span class="line"> <span class="attr">owner:</span> <span class="string">root</span></span><br><span class="line"> <span class="attr">group:</span> <span class="string">root</span></span><br><span class="line"> <span class="attr">mode:</span> <span class="string">'0644'</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Deploy</span> <span class="number">01</span><span class="string">-external.conf</span></span><br><span class="line"> <span class="attr">template:</span></span><br><span class="line"> <span class="attr">src:</span> <span class="number">01</span><span class="string">-external.conf.j2</span></span><br><span class="line"> <span class="attr">dest:</span> <span class="string">/etc/ssh/sshd_config.d/01-external.conf</span></span><br><span class="line"> <span class="attr">owner:</span> <span class="string">root</span></span><br><span class="line"> <span class="attr">group:</span> <span class="string">root</span></span><br><span class="line"> <span class="attr">mode:</span> <span class="string">'0644'</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Restart</span> <span class="string">ssh</span> <span class="string">service</span></span><br><span class="line"> <span class="attr">service:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">ssh</span></span><br><span class="line"> <span class="attr">state:</span> <span class="string">restarted</span></span><br></pre></td></tr></table></figure>
<h3 id="Template-sshd-config-j2"><a href="#Template-sshd-config-j2" class="headerlink" title="Template sshd_config.j2"></a>Template <code>sshd_config.j2</code></h3><p>Questo ricalca le configurazioni base:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">UsePAM yes</span><br><span class="line">PermitRootLogin no</span><br><span class="line">ChallengeResponseAuthentication no</span><br><span class="line">PasswordAuthentication yes</span><br><span class="line">PubkeyAuthentication yes</span><br><span class="line">Include /etc/ssh/sshd_config.d/*.conf</span><br></pre></td></tr></table></figure>
<h3 id="Template-00-internal-conf-j2"><a href="#Template-00-internal-conf-j2" class="headerlink" title="Template 00-internal.conf.j2"></a>Template <code>00-internal.conf.j2</code></h3><p>Consente da rete interna l’uso della password e delle chiavi a qualsiasi utente:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Match address {{ internal_network }}</span><br><span class="line"> PasswordAuthentication yes</span><br><span class="line"> PubkeyAuthentication yes</span><br></pre></td></tr></table></figure>
<h3 id="Template-01-external-conf-j2"><a href="#Template-01-external-conf-j2" class="headerlink" title="Template 01-external.conf.j2"></a>Template <code>01-external.conf.j2</code></h3><p>Limitato all’utente <code>deploy</code> e all’indirizzo IP esterno, solo chiave:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Match User {{ external_user }}, Address {{ external_ip }}</span><br><span class="line"> PasswordAuthentication no</span><br><span class="line"> PubkeyAuthentication yes</span><br></pre></td></tr></table></figure>
<h2 id="Port-Forwarding-su-Porta-Alta-22222"><a href="#Port-Forwarding-su-Porta-Alta-22222" class="headerlink" title="Port Forwarding su Porta Alta (22222)"></a>Port Forwarding su Porta Alta (22222)</h2><p>Dal lato del router, come nel precedente articolo, si configura il port forwarding della porta 22222 esterna verso la 22 interna del server. Ansible non può effettuare questa operazione sul router a meno di avere plugin specifici o un router programmabile (ad esempio via API). Presumiamo che questa modifica sia stata già fatta a mano sul router:</p>
<ul>
<li>Dall’esterno: <code>ssh -p 22222 deploy@mio_dominio</code><br>Il router inoltra la 22222 → 22 del server interno.</li>
</ul>
<p>Nella configurazione di Ansible non cambia nulla per <code>sshd</code>, rimane in ascolto sulla 22 interna. Il firewall filtra gli accessi, l’utente <code>deploy</code> può accedere solo dall’<code>external_ip</code> consentito con chiave, mentre la rete interna può accedere con password.</p>
<p>Se si volesse essere più coerenti, potremmo cambiare la <code>Port</code> in <code>sshd_config.j2</code>. Tuttavia, il port forwarding è una soluzione migliore, perché non richiede modifiche al demone SSH e non influisce sugli accessi LAN.</p>
<h2 id="Eseguire-il-Playbook"><a href="#Eseguire-il-Playbook" class="headerlink" title="Eseguire il Playbook"></a>Eseguire il Playbook</h2><p>Dopo aver preparato tutto:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ansible-playbook -i inventory.ini playbook.yaml</span><br></pre></td></tr></table></figure>
<p>Se il vostro accesso SSH al server è pronto, Ansible applicherà in pochi secondi tutte le configurazioni descritte. Eseguite nuovamente il playbook in futuro per mantenere lo stato o dopo modifiche alle variabili: le configurazioni saranno sempre coerenti.</p>
<h2 id="Possibili-Estensioni-e-Conclusione"><a href="#Possibili-Estensioni-e-Conclusione" class="headerlink" title="Possibili Estensioni e Conclusione"></a>Possibili Estensioni e Conclusione</h2><p>In questo articolo abbiamo replicato l’approccio modulare e differenziato dell’accesso SSH mediante la creazione e applicazione automatizzata di playbook Ansible. Questo consente di scalare la stessa configurazione su più server e di mantenere un controllo centralizzato, coerente e privo di rischi di errore umano.</p>
<p>Per ulteriori estensioni future, si potrebbero creare ruoli separati per la gestione delle chiavi SSH, per l’applicazione di policy di sicurezza più complesse, per l’integrazione con sistemi di gestione delle identità o per la distribuzione automatica di fail2ban con configurazioni personalizzate.<br>Inoltre, si potrebbe integrare Ansible con strumenti CI/CD per testare automaticamente le configurazioni prima del deployment in produzione.</p>
<p>Con l’introduzione di Ansible, abbiamo compiuto un passo significativo verso l’automazione dell’infrastruttura e la riduzione del carico di lavoro amministrativo, garantendo un accesso SSH sicuro, modulare e facile da mantenere.</p>
</div>
<footer class="article-footer">
<a data-url="https://geegeek.github.io/2024/12/09/Automatizzare-la-configurazione-differenziata-dell-accesso-SSH-con-Ansible/" data-id="cm5wmibch000135j9h0xdh5bx" data-title="Automatizzare la configurazione differenziata dell'accesso SSH con Ansible" class="article-share-link"><span class="fa fa-share">Share</span></a>
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/ansible/" rel="tag">ansible</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/automazione/" rel="tag">automazione</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/linux/" rel="tag">linux</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/networking/" rel="tag">networking</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/sicurezza/" rel="tag">sicurezza</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/ssh/" rel="tag">ssh</a></li></ul>
</footer>
</div>
</article>
<article id="post-Implementare-un-server-SSH-su-Ubuntu-Debian-configurazioni-differenziate-e-accesso-esterno-con-port-forwarding" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<div class="article-meta">
<a href="/2024/12/09/Implementare-un-server-SSH-su-Ubuntu-Debian-configurazioni-differenziate-e-accesso-esterno-con-port-forwarding/" class="article-date">
<time class="dt-published" datetime="2024-12-09T00:00:00.000Z" itemprop="datePublished">2024-12-09</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="p-name article-title" href="/2024/12/09/Implementare-un-server-SSH-su-Ubuntu-Debian-configurazioni-differenziate-e-accesso-esterno-con-port-forwarding/">Implementare un server SSH su Ubuntu/Debian, configurazioni differenziate e accesso esterno con port forwarding</a>
</h1>
</header>
<div class="e-content article-entry" itemprop="articleBody">
<h2 id="Introduzione"><a href="#Introduzione" class="headerlink" title="Introduzione"></a>Introduzione</h2><p>In questo articolo approfondiremo la configurazione di un server SSH su Ubuntu/Debian con un livello di sicurezza un po’ piu’ elevato. Non ci limiteremo alla semplice attivazione del servizio, ma esploreremo una strategia di configurazione modulare utilizzando la directory <code>sshd_config.d</code>. Questo approccio consente di creare differenti casistiche di accesso in base alla rete di provenienza, al metodo di autenticazione e all’utente che tenta di collegarsi. Inoltre, vedremo come:</p>
<ul>
<li>Limitare gli accessi esterni a determinati utenti e chiavi pubbliche, filtrando per indirizzi IP di origine.</li>
<li>Permettere, da rete interna, l’accesso anche con password per tutti gli utenti.</li>
<li>Integrare firewall e fail2ban per mitigare i tentativi di accesso non autorizzati.</li>
<li>Esporre la porta SSH su una porta alta tramite port forwarding, aumentandone la sicurezza.</li>
<li>Preparare il terreno per automatizzare questi processi in futuro.</li>
</ul>
<p>Assumeremo i seguenti prerequisiti:</p>
<ul>
<li>Il server è basato su Ubuntu/Debian con <code>sudo</code> abilitato per l’utente di amministrazione.</li>
<li>OpenSSH Server è installato.</li>
<li>Un firewall (ad esempio <code>ufw</code>) è attivo e configurato.</li>
<li>Fail2ban è installato per prevenire i tentativi di brute-force.</li>
<li>Il server dispone di un IP interno (LAN) e di un IP pubblico (o di un router con port forwarding configurabile).</li>
<li>L’utente di amministrazione appartiene al gruppo <code>sudo</code>.</li>
</ul>
<h2 id="Perche’�-adottare-una-configurazione-modulare-con-sshd-config-d"><a href="#Perche’�-adottare-una-configurazione-modulare-con-sshd-config-d" class="headerlink" title="Perche’� adottare una configurazione modulare con sshd_config.d"></a>Perche’� adottare una configurazione modulare con sshd_config.d</h2><p>Il file principale <code>/etc/ssh/sshd_config</code> definisce il comportamento globale del server SSH. Tuttavia, utilizzando la directory <code>/etc/ssh/sshd_config.d</code>, possiamo inserire file aggiuntivi che sovrascrivono o integrano la configurazione di base. Questo approccio modulare permette di mantenere il file principale pulito e di organizzare le diverse casistiche di accesso in file separati. È particolarmente utile quando si gestiscono scenari complessi e si ha necessità di apportare modifiche incrementali senza rischiare di compromettere l’intera configurazione.</p>
<h2 id="Configurazione-di-base-di-OpenSSH"><a href="#Configurazione-di-base-di-OpenSSH" class="headerlink" title="Configurazione di base di OpenSSH"></a>Configurazione di base di OpenSSH</h2><h3 id="Installazione"><a href="#Installazione" class="headerlink" title="Installazione"></a>Installazione</h3><p>Se non lo avete già fatto, procedete all’installazione:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> apt update</span><br><span class="line"><span class="built_in">sudo</span> apt install openssh-server</span><br></pre></td></tr></table></figure>
<p>Il servizio <code>sshd</code> sarà avviato e abilitato automaticamente.</p>
<h3 id="Configurazione-del-firewall-UFW"><a href="#Configurazione-del-firewall-UFW" class="headerlink" title="Configurazione del firewall (UFW)"></a>Configurazione del firewall (UFW)</h3><p>Assicuratevi che il firewall <code>ufw</code> sia installato e attivato:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> apt install ufw</span><br><span class="line"><span class="built_in">sudo</span> ufw <span class="built_in">enable</span></span><br></pre></td></tr></table></figure>
<p>Per consentire la connessione sulla porta SSH standard (22), eseguite:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> ufw allow 22/tcp</span><br></pre></td></tr></table></figure>
<p>Successivamente, quando imposteremo un port forwarding su una porta differente, modificheremo le regole di conseguenza.</p>
<h3 id="Configurazione-di-fail2ban"><a href="#Configurazione-di-fail2ban" class="headerlink" title="Configurazione di fail2ban"></a>Configurazione di fail2ban</h3><p>Fail2ban blocca gli indirizzi IP che tentano di eseguire accessi non autorizzati (brute-force). Se non presente:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> apt install fail2ban</span><br></pre></td></tr></table></figure>
<p>Nella configurazione predefinita, fail2ban monitorerà il file di log di SSH e bloccherà automaticamente gli IP che generano troppi tentativi falliti. È possibile personalizzare <code>/etc/fail2ban/jail.local</code> per definire tempi di ban, numero di tentativi e altro. Un esempio basilare (da aggiungere o modificare in <code>/etc/fail2ban/jail.local</code>):</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">[sshd]</span><br><span class="line">enabled = true</span><br><span class="line">port = 22</span><br><span class="line">filter = sshd</span><br><span class="line">logpath = /var/log/auth.log</span><br><span class="line">maxretry = 5</span><br><span class="line">findtime = 600</span><br><span class="line">bantime = 3600</span><br></pre></td></tr></table></figure>
<p>Dopo aver modificato i parametri:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> systemctl restart fail2ban</span><br></pre></td></tr></table></figure>
<p>Con questa configurazione di base, fallimenti ripetuti di autenticazione verranno puniti con il blocco temporaneo dell’IP.</p>
<h3 id="Gestione-utenti-e-privilegi-sudo"><a href="#Gestione-utenti-e-privilegi-sudo" class="headerlink" title="Gestione utenti e privilegi sudo"></a>Gestione utenti e privilegi sudo</h3><p>L’utente amministrativo dovrebbe appartenere al gruppo <code>sudo</code>. Se state utilizzando un utente diverso, potete aggiungerlo al gruppo:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> adduser mio_utente</span><br><span class="line"><span class="built_in">sudo</span> usermod -aG <span class="built_in">sudo</span> mio_utente</span><br></pre></td></tr></table></figure>
<p>In questo modo <code>mio_utente</code> potrà eseguire comandi <code>sudo</code> e gestire la configurazione del sistema.</p>
<h2 id="Creazione-di-scenari-differenziati"><a href="#Creazione-di-scenari-differenziati" class="headerlink" title="Creazione di scenari differenziati"></a>Creazione di scenari differenziati</h2><p>L’obiettivo è creare due casi d’uso:</p>
<ol>
<li><p><strong>Accessi dall’esterno:</strong> </p>
<ul>
<li>Limitati a specifici utenti (ad esempio <code>deploy</code>) </li>
<li>Limitati a specifici IP di origine </li>
<li>Autenticazione <strong>solo con chiave</strong>, niente password.</li>
</ul>
</li>
<li><p><strong>Accessi dalla rete interna:</strong> </p>
<ul>
<li>Consentiti per tutti gli utenti di sistema (ad esempio <code>mio_utente</code> o altri) </li>
<li>Autenticazione con password abilitata e chiavi ammessa </li>
<li>Nessuna restrizione di IP (ma ci si basa sul fatto che l’indirizzo IP provenga dalla rete interna, ad esempio <code>192.168.0.0/24</code>).</li>
</ul>
</li>
</ol>
<h3 id="Configurazione-di-base-di-etc-ssh-sshd-config"><a href="#Configurazione-di-base-di-etc-ssh-sshd-config" class="headerlink" title="Configurazione di base di /etc/ssh/sshd_config"></a>Configurazione di base di <code>/etc/ssh/sshd_config</code></h3><p>Nel file principale <code>/etc/ssh/sshd_config</code> lasceremo impostazioni generali di sicurezza:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> <span class="built_in">cp</span> /etc/ssh/sshd_config /etc/ssh/sshd_config.bak</span><br></pre></td></tr></table></figure>
<p>Modifichiamo <code>/etc/ssh/sshd_config</code> per disabilitare l’accesso root e alcune opzioni generali:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">UsePAM yes</span><br><span class="line">PermitRootLogin no</span><br><span class="line">ChallengeResponseAuthentication no</span><br><span class="line">PasswordAuthentication yes # Abilitiamo qui la password come default, poi la limitiamo nei match esterni</span><br><span class="line">PubkeyAuthentication yes</span><br><span class="line"># Includiamo la directory di configurazione aggiuntiva</span><br><span class="line">Include /etc/ssh/sshd_config.d/*.conf</span><br></pre></td></tr></table></figure>
<p>Salviamo e chiudiamo. Con <code>Include /etc/ssh/sshd_config.d/*.conf</code> abbiamo dato istruzioni a <code>sshd</code> di leggere file aggiuntivi nella directory <code>sshd_config.d</code>.</p>
<h3 id="Creazione-dei-file-di-configurazione-modulari"><a href="#Creazione-dei-file-di-configurazione-modulari" class="headerlink" title="Creazione dei file di configurazione modulari"></a>Creazione dei file di configurazione modulari</h3><p>Creeremo due file all’interno di <code>/etc/ssh/sshd_config.d</code>:</p>
<ul>
<li><code>00-internal.conf</code> per la rete interna</li>
<li><code>01-external.conf</code> per l’accesso esterno</li>
</ul>
<h4 id="Configurazione-interna-etc-ssh-sshd-config-d-00-internal-conf"><a href="#Configurazione-interna-etc-ssh-sshd-config-d-00-internal-conf" class="headerlink" title="Configurazione interna: /etc/ssh/sshd_config.d/00-internal.conf"></a>Configurazione interna: <code>/etc/ssh/sshd_config.d/00-internal.conf</code></h4><p>Questa configurazione consente a chiunque si trovi all’interno della rete interna (es. <code>192.168.0.0/24</code>) di autenticarsi con password:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> nano /etc/ssh/sshd_config.d/00-internal.conf</span><br></pre></td></tr></table></figure>
<p>Inseriamo:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Match address 192.168.0.0/24</span><br><span class="line"> PasswordAuthentication yes</span><br><span class="line"> PubkeyAuthentication yes</span><br><span class="line"> # In questo scenario lasciamo qualsiasi utente della LAN entrare con password o chiave.</span><br></pre></td></tr></table></figure>
<p>Salviamo e chiudiamo.</p>
<h4 id="Configurazione-esterna-etc-ssh-sshd-config-d-01-external-conf"><a href="#Configurazione-esterna-etc-ssh-sshd-config-d-01-external-conf" class="headerlink" title="Configurazione esterna: /etc/ssh/sshd_config.d/01-external.conf"></a>Configurazione esterna: <code>/etc/ssh/sshd_config.d/01-external.conf</code></h4><p>Per l’accesso esterno, supponiamo di avere un IP pubblico o di filtrare l’accesso tramite firewall. Ad esempio, immaginiamo che solo da un certo IP pubblico o da un range (ad esempio <code>aa.bb.cc.dd</code>) possa accedere l’utente <code>deploy</code>. Inoltre, vogliamo obbligare l’autenticazione solo tramite chiave.</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> nano /etc/ssh/sshd_config.d/01-external.conf</span><br></pre></td></tr></table></figure>
<p>Inseriamo:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Match User deploy, Address aa.bb.cc.dd</span><br><span class="line"> PasswordAuthentication no</span><br><span class="line"> PubkeyAuthentication yes</span><br></pre></td></tr></table></figure>
<p>In questo modo, se la connessione proviene dall’indirizzo <code>aa.bb.cc.dd</code> e l’utente che tenta di accedere è <code>deploy</code>, la password non sarà accettata, ma solo la chiave pubblica. Nessun altro IP o utente potrà usufruire di queste impostazioni.</p>
<h3 id="Riavviare-il-servizio-SSH-per-applicare-le-modifiche"><a href="#Riavviare-il-servizio-SSH-per-applicare-le-modifiche" class="headerlink" title="Riavviare il servizio SSH per applicare le modifiche"></a>Riavviare il servizio SSH per applicare le modifiche</h3><p>Dopo aver creato i file di configurazione, riavviamo SSH:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> systemctl restart ssh</span><br></pre></td></tr></table></figure>
<h2 id="Chiavi-SSH"><a href="#Chiavi-SSH" class="headerlink" title="Chiavi SSH"></a>Chiavi SSH</h2><p>L’utente <code>deploy</code> che accede da remoto dovrà avere una coppia di chiavi. Sul client remoto, generiamo una chiave:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh-keygen -t ed25519 -C <span class="string">"[email protected]"</span></span><br></pre></td></tr></table></figure>
<p>Copiare la chiave pubblica sul server (da remoto):</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh-copy-id deploy@ip_o_dominio_del_server</span><br></pre></td></tr></table></figure>
<p>Il comando <code>ssh-copy-id</code> aggiungerà la chiave a <code>~/.ssh/authorized_keys</code> dell’utente <code>deploy</code>.</p>
<h2 id="Configurazione-del-firewall-per-differenti-casistiche"><a href="#Configurazione-del-firewall-per-differenti-casistiche" class="headerlink" title="Configurazione del firewall per differenti casistiche"></a>Configurazione del firewall per differenti casistiche</h2><p>Poiché da esterno si deve accedere solo con chiave e da determinati IP, si puo’ò rafforzare il tutto tramite <code>ufw</code>, consentendo solo l’IP esterno specifico:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> ufw allow from aa.bb.cc.dd to any port 22</span><br></pre></td></tr></table></figure>
<p>Se desiderate bloccare tutti gli altri tentativi di accesso esterni, assicuratevi di non eseguire un <code>ufw allow 22/tcp</code> generico, ma solo quello limitato all’IP sopra indicato. In caso foste costretti ad aprire a tutti l’accesso per qualche motivo, ricordate che fail2ban entra in azione per mitigare i tentativi di brute force.</p>
<h2 id="Fail2ban-e-le-due-casistiche-di-accesso"><a href="#Fail2ban-e-le-due-casistiche-di-accesso" class="headerlink" title="Fail2ban e le due casistiche di accesso"></a>Fail2ban e le due casistiche di accesso</h2><p>Fail2ban non fa distinzioni tra accessi interni o esterni di default, ma grazie alla sua configurazione blocca gli IP che tentano numerosi accessi non autorizzati. Questo è utile specialmente per gli attacchi provenienti da Internet. Se notate che IP interni vengono bloccati, potete modificare la configurazione <code>ignoreip</code> in <code>/etc/fail2ban/jail.local</code>:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">[sshd]</span><br><span class="line">enabled = true</span><br><span class="line">port = 22</span><br><span class="line">filter = sshd</span><br><span class="line">logpath = /var/log/auth.log</span><br><span class="line">maxretry = 5</span><br><span class="line">findtime = 600</span><br><span class="line">bantime = 3600</span><br><span class="line">ignoreip = 127.0.0.1/8 192.168.0.0/24</span><br></pre></td></tr></table></figure>
<p>In questo modo gli IP interni non saranno bloccati, permettendo maggiore flessibilità nella LAN.</p>
<p>Dopo le modifiche:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> systemctl restart fail2ban</span><br></pre></td></tr></table></figure>
<h2 id="Spostare-la-porta-SSH-esterna-su-una-porta-alta-con-port-forwarding"><a href="#Spostare-la-porta-SSH-esterna-su-una-porta-alta-con-port-forwarding" class="headerlink" title="Spostare la porta SSH esterna su una porta alta con port forwarding"></a>Spostare la porta SSH esterna su una porta alta con port forwarding</h2><p>È una buona pratica non esporre la porta 22 direttamente su Internet. Si può configurare il router per effettuare un port forwarding da una porta alta (ad esempio 22222) verso la porta 22 del server.</p>
<h3 id="Passi-generali"><a href="#Passi-generali" class="headerlink" title="Passi generali"></a>Passi generali</h3><ol>
<li><p><strong>Sul router/NAT:</strong><br>Accedete all’interfaccia di gestione del vostro router e individuate la sezione “Port Forwarding” o “Virtual Server”.<br>Create una regola che inoltri la porta esterna 22222 (TCP) all’indirizzo IP interno del vostro server sulla porta 22.</p>
</li>
<li><p><strong>Configurazione del firewall interno per la nuova porta:</strong></p>
<p>Poiché la porta 22 rimane aperta internamente, nella rete LAN tutto rimane come prima. Dall’esterno, però, l’utente si collegherà a <code>ssh -p 22222 deploy@mio_dominio</code> (se avete un nome di dominio puntato sul vostro IP pubblico).</p>
<p>Se volete che il firewall accetti esplicitamente connessioni solo su 22 in LAN e non dall’esterno, potete chiudere la 22 dall’esterno e lasciare aperta solo tramite la regola del router:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> ufw deny 22/tcp</span><br></pre></td></tr></table></figure>
<p>Ma questo bloccherebbe completamente SSH via 22 (anche internamente), quindi meglio gestire il firewall sul router o, se il server deve essere raggiungibile da LAN su 22, lasciare <code>ufw allow 22/tcp</code> ma consentire accesso esterno solo tramite l’IP specifico. Dipende dalla vostra topologia di rete.<br>Se volete segmentare, potete usare regole UFW avanzate per differenziare l’accesso esterno/interno (ad esempio definendo <code>allow from 192.168.0.0/24 to any port 22</code> per la LAN, e negare tutto il resto).</p>
</li>
</ol>
<h3 id="Collegamento-esterno-sulla-porta-alta"><a href="#Collegamento-esterno-sulla-porta-alta" class="headerlink" title="Collegamento esterno sulla porta alta"></a>Collegamento esterno sulla porta alta</h3><p>Da un host remoto:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh -p 22222 deploy@mio_dominio</span><br></pre></td></tr></table></figure>
<p>La connessione arriverà al vostro router, che la inoltrerà alla porta 22 del server, passando le regole di <code>sshd</code>. Ricordate che l’utente <code>deploy</code> ha l’accesso da quell’IP autorizzato e soltanto con chiave.</p>
<h2 id="Considerazioni-finali-e-spunti-per-l’automazione"><a href="#Considerazioni-finali-e-spunti-per-l’automazione" class="headerlink" title="Considerazioni finali e spunti per l’automazione"></a>Considerazioni finali e spunti per l’automazione</h2><p>Abbiamo creato una configurazione modulare che differenzia gli accessi SSH sulla base della rete di provenienza, del metodo di autenticazione e dell’utente, utilizzando i file in <code>sshd_config.d</code>. Abbiamo integrato firewall, fail2ban e illustrato come effettuare un port forwarding per aumentare la sicurezza.</p>
<p>Questo approccio è solido, ma la sua gestione manuale puo’ò diventare complessa in ambienti di grandi dimensioni o con frequenti variazioni. Nel prossimo articolo potremmo esplorare meccanismi di <strong>automazione</strong>, utilizzando tool come Ansible, Puppet o Chef, per distribuire e mantenere queste configurazioni in maniera scalabile e ripetibile. L’automazione permetterebbe di applicare, testare e aggiornare queste configurazioni su un parco macchine esteso, riducendo il rischio di errori umani e semplificando il lavoro dell’amministratore di sistema.</p>
<p>Con questi spunti, si chiude questo lungo articolo, augurandoci che le informazioni fornite siano utili per implementare un accesso SSH sicuro, flessibile e ben organizzato.</p>
<h2 id="Possibili-Miglioramenti"><a href="#Possibili-Miglioramenti" class="headerlink" title="Possibili Miglioramenti"></a>Possibili Miglioramenti</h2><p>Un ulteriore passo avanti verso una configurazione più robusta e scalabile potrebbe essere l’utilizzo di un reverse proxy posizionato davanti alla porta SSH esposta su Internet. In particolare, adottare un servizio come Cloudflare (gratuito nella fascia free per il traffico su porte HTTP/HTTPS, ma non per la porta SSH) consentirebbe di usufruire della loro rete globale di distribuzione, di strumenti di mitigazione avanzati contro attacchi DDoS, e di ulteriori livelli di filtraggio del traffico.</p>
<p>Tuttavia, questa configurazione introduce complessità aggiuntive: occorrerebbe consentire l’accesso solo agli indirizzi IP di Cloudflare, con una conseguente modifica delle regole firewall, una gestione più granulare delle liste di trusted IP e una combinazione di impostazioni su Cloudflare stesso.</p>
<p>Questa soluzione, pur più articolata, incrementa significativamente la resilienza del sistema e riduce l’esposizione diretta della vostra infrastruttura, rendendola meno vulnerabile alle minacce provenienti da Internet. Consideratela un’evoluzione del setup descritto in quest’articolo, una strada da intraprendere quando le esigenze di sicurezza e affidabilità diventano più stringenti.</p>
</div>
<footer class="article-footer">
<a data-url="https://geegeek.github.io/2024/12/09/Implementare-un-server-SSH-su-Ubuntu-Debian-configurazioni-differenziate-e-accesso-esterno-con-port-forwarding/" data-id="cm5wmibd5000d35j97eczcbj6" data-title="Implementare un server SSH su Ubuntu/Debian, configurazioni differenziate e accesso esterno con port forwarding" class="article-share-link"><span class="fa fa-share">Share</span></a>
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/automazione/" rel="tag">automazione</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/linux/" rel="tag">linux</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/networking/" rel="tag">networking</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/sicurezza/" rel="tag">sicurezza</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/ssh/" rel="tag">ssh</a></li></ul>
</footer>
</div>
</article>
<article id="post-Gestire-la-configurazione-di-rete-con-il-comando-ip-su-Linux" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<div class="article-meta">
<a href="/2024/12/08/Gestire-la-configurazione-di-rete-con-il-comando-ip-su-Linux/" class="article-date">
<time class="dt-published" datetime="2024-12-08T00:00:00.000Z" itemprop="datePublished">2024-12-08</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="p-name article-title" href="/2024/12/08/Gestire-la-configurazione-di-rete-con-il-comando-ip-su-Linux/">Gestire la configurazione di rete con il comando ip su Linux</a>
</h1>
</header>
<div class="e-content article-entry" itemprop="articleBody">
<h2 id="Introduzione"><a href="#Introduzione" class="headerlink" title="Introduzione"></a>Introduzione</h2><p>Il comando <strong>ip</strong> su Linux è uno strumento estremamente versatile e potente per la gestione e la configurazione dei parametri di rete del sistema. Sostituisce gradualmente alcuni comandi più datati (come <code>ifconfig</code>, <code>route</code>, <code>netstat</code>) offrendo funzionalità più moderne e una sintassi coerente. Grazie a <strong>ip</strong> è possibile visualizzare, modificare e mantenere in efficienza la rete locale, le interfacce, i gateway e le rotte in modo sicuro, scalabile e senza ricorrere ad azioni rischiose.</p>
<p>In questo articolo esamineremo, in un ordine più coerente rispetto alla lista originale, come utilizzare il comando <strong>ip</strong> per coprire una serie di attività comuni in ambito di amministrazione di rete. Saranno illustrate le funzioni principali, la configurazione di base consigliata, alcune opzioni utili e le best practice per mantenere un livello di sicurezza medio-alto, senza ricorrere ad un accesso root diretto.</p>
<h2 id="Perche-usare-il-comando-ip"><a href="#Perche-usare-il-comando-ip" class="headerlink" title="Perché usare il comando ip?"></a>Perché usare il comando ip?</h2><p>Il comando <strong>ip</strong> fa parte del pacchetto <code>iproute2</code> e offre una sintassi modulare in cui le operazioni si esprimono come combinazioni di <code>ip [oggetto] [comando] [parametri]</code>. Gli oggetti principali sono <code>link</code> (le interfacce), <code>addr</code> (gli indirizzi IP), <code>route</code> (le rotte), <code>neigh</code> (gli ARP/neighbour), e così via.</p>
<p>Rispetto ad altri comandi datati, <strong>ip</strong> fornisce un output più chiaro, supporta funzionalità moderne (come tunnel e policy routing) e permette di integrare opzioni avanzate (es. gestione di MTU, queueing discipline, bridging, bonding).</p>
<h2 id="Ordine-logico-delle-operazioni-con-il-comando-ip"><a href="#Ordine-logico-delle-operazioni-con-il-comando-ip" class="headerlink" title="Ordine logico delle operazioni con il comando ip"></a>Ordine logico delle operazioni con il comando ip</h2><p>Di seguito una lista ordinata di 15 azioni comuni che si possono effettuare con il comando <strong>ip</strong>, riorganizzate in un ordine più coerente per un amministratore di sistema:</p>
<ol>
<li><p><strong>Individuare le interfacce di rete disponibili sul sistema</strong><br>Prima di qualsiasi operazione è fondamentale sapere quali interfacce siano presenti: Ethernet, Wi-Fi, loopback, virtuali ecc.</p>
</li>
<li><p><strong>Consultare lo stato di una singola interfaccia IP</strong><br>Una volta individuata un’interfaccia, è utile controllarne stato, parametri e statistiche.</p>
</li>
<li><p><strong>Configurare l’interfaccia di loopback, Ethernet e altre interfacce IP</strong><br>Il loopback e le interfacce fisiche o virtuali possono essere configurate con indirizzi IP, MTU, etichette, ecc.</p>
</li>
<li><p><strong>Mettere un’interfaccia in stato attivo (up) o inattivo (down)</strong><br>Attivare o disattivare un’interfaccia senza rimuoverne la configurazione.</p>
</li>
<li><p><strong>Modificare parametri aggiuntivi di un’interfaccia, ad esempio MTU o nome</strong><br>Non solo up/down, ma anche impostare l’MTU e, se supportato, rinominare l’interfaccia in modo coerente.</p>
</li>
<li><p><strong>Assegnare, eliminare e configurare indirizzi IP, subnet e altre informazioni IP</strong><br>Aggiungere un indirizzo IP, rimuoverlo, configurare maschere di rete e gateway può essere fatto con pochi comandi.</p>
</li>
<li><p><strong>Visualizzare e modificare l’elenco degli indirizzi IP e le loro proprietà</strong><br>Effettuare un inventario degli indirizzi configurati, controllare indirizzi multipli su una singola interfaccia, ecc.</p>
</li>
<li><p><strong>Configurare e modificare rotte predefinite e statiche</strong><br>Impostare una route di default o aggiungere rotte statiche verso sottoreti specifiche.</p>
</li>
<li><p><strong>Impostare o eliminare singole voci di routing</strong><br>Se necessario, aggiungere o rimuovere rotte individuali per un fine più granulare.</p>
</li>
<li><p><strong>Verificare il percorso (traccia) che un indirizzo IP seguirà</strong><br>Controllare come i pacchetti raggiungono una destinazione, utile per diagnosticare problemi di rete.</p>
</li>
<li><p><strong>Configurare tunnel su IP</strong><br>Creare e gestire tunnel IP (ad esempio GRE o IPIP) per connettere due reti remote attraverso un canale sicuro.</p>
</li>
<li><p><strong>Gestire e visualizzare lo stato globale della rete</strong><br>Panoramica dello stato di tutte le interfacce e delle relative statistiche.</p>
</li>
<li><p><strong>Raccogliere informazioni sugli indirizzi IP multicast</strong><br>Verificare quali gruppi multicast sono configurati sull’host.</p>
</li>
<li><p><strong>Mostrare la cache ARP o NDISC</strong><br>Visualizzare i mapping tra indirizzi IP e MAC (ARP su IPv4) o NDISC (su IPv6).</p>
</li>
<li><p><strong>Gestire gli oggetti neighbour: invalidare ARP cache, aggiungere entry ARP, ecc.</strong><br>Aggiungere manualmente voci ARP, rimuoverle o invalidarle per forzare la risoluzione dell’indirizzo in caso di problemi.</p>
</li>
</ol>
<h2 id="Comandi-utili-ed-esempi-di-configurazione"><a href="#Comandi-utili-ed-esempi-di-configurazione" class="headerlink" title="Comandi utili ed esempi di configurazione"></a>Comandi utili ed esempi di configurazione</h2><p>Di seguito riportiamo alcuni esempi pratici, usando il comando <code>ip</code>.<br><strong>Nota:</strong> Evita di operare come root; utilizza invece <code>sudo</code> quando necessario. Prima di modificare configurazioni critiche di rete, sperimenta su macchine di test o sistemi non di produzione.</p>
<h3 id="1-Individuare-le-interfacce-disponibili"><a href="#1-Individuare-le-interfacce-disponibili" class="headerlink" title="1. Individuare le interfacce disponibili"></a>1. Individuare le interfacce disponibili</h3><pre><code class="bash">ip link show
### 2. Consultare lo stato di una singola interfaccia
```bash
ip link show dev eth0
Questo comando mostra lo stato di `eth0`, le sue proprietà e se è up o down.
### 3. Configurare l’interfaccia di loopback
L’interfaccia loopback `lo` è solitamente già configurata di default, ma per verificarne lo stato:
```bash
ip link set lo up
ip addr show dev lo
### 4. Attivare o disattivare un’interfaccia
```bash
sudo ip link set eth0 up
sudo ip link set eth0 down
### 5. Modificare parametri avanzati dell’interfaccia
Ad esempio, per modificare l’MTU:
```bash
sudo ip link set eth0 mtu 1400
### 6. Assegnare un indirizzo IP
```bash
sudo ip addr add 192.168.1.10/24 dev eth0
Per rimuoverlo:
```bash
sudo ip addr del 192.168.1.10/24 dev eth0
### 7. Visualizzare gli indirizzi IP configurati
```bash
ip addr show
### 8. Configurare una route di default