Repository navigation
Expand file tree
/
Copy pathfeed.xml
More file actions
1070 lines (666 loc) · 144 KB
/
Copy pathfeed.xml
File metadata and controls
1070 lines (666 loc) · 144 KB
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
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="https://stephan-lopes.github.io/blog/feed.xml" rel="self" type="application/atom+xml" /><link href="https://stephan-lopes.github.io/blog/" rel="alternate" type="text/html" /><updated>2022-07-18T03:00:47+00:00</updated><id>https://stephan-lopes.github.io/blog/feed.xml</id><title type="html">K.</title><subtitle>Um blog sobre tecnologia, programação e computação.</subtitle><entry><title type="html">Comandos Linux: Exec</title><link href="https://stephan-lopes.github.io/blog/comandos-linux-exec/" rel="alternate" type="text/html" title="Comandos Linux: Exec" /><published>2022-07-17T22:00:00+00:00</published><updated>2022-07-17T22:00:00+00:00</updated><id>https://stephan-lopes.github.io/blog/comandos-linux-exec</id><content type="html" xml:base="https://stephan-lopes.github.io/blog/comandos-linux-exec/"><p><em>No artigo anterior desta série de artigos, o leitor obteve conhecimentos sobre o comando alias. Ele é um dos comandos embutidos no bash. Esses comandos embutidos, também conhecidos como built-in, apesar de parecerem simples, são poderosos, já que possibilitam uma comunicação mais rápida com recursos do sistema. Um desses comandos embutidos, permite com que o usuário utilize descritores de arquivos de uma forma mais prática. O comando exec, permite realizar essa manipulação, além de fazer a sua função principal: executar um novo programa no mesmo processo em que está, sem utilizar uma subshell. Neste artigo, o leitor será introduzido ao comando exec e aos conceitos de sistemas operacionais, exec e fork.</em></p>
<h2 id="_-o-comando-exec">&gt;_ O Comando Exec</h2>
<p>O <strong>comando exec</strong> permite executar um comando sem criar uma <em>subshell</em>. Com ele, é até mesmo possível redirecionar descritores padrões de arquivos. Ele permite executar comandos com qualquer quantidade de argumentos. Qualquer argumento passado para o <strong>exec</strong>, será tratado como argumento do comando que está sendo passado. É importante frisar também que, quando não usado com descritores, ele utiliza códigos de retorno para o <em>shell</em>. Isso faz com que, ao final da execução daquele programa, o processo seja encerrado.</p>
<p>Um exemplo de como funciona a sua interpretação, seria a seguinte:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec</span> <span class="o">{</span>comando<span class="o">}</span> <span class="o">{</span>1...N argumentos <span class="k">do </span>comando<span class="o">}</span>
</code></pre></div></div>
<p>O <strong>comando exec</strong>, segue o mesmo conceito do <strong>exec</strong> presente em <strong>sistemas operacionais</strong>.</p>
<p>Em <strong>sistemas operacionais</strong>, um processo pode ser filho de outro, o que é chamado de <strong>fork</strong> (existem alguns detalhes que serão explicados mais adiante). Já o <strong>exec</strong>, permite a execução de um processo, sem a criação de um processo filho.</p>
<p>Se é a primeira vez que o leitor se depara com esses termos, não deve se preocupar. Ao decorrer do artigo, serão dadas mais explicações sobre os termos tratados acima.</p>
<h2 id="_-uma-breve-introdução-ao-fork">&gt;_ Uma breve introdução ao Fork</h2>
<p>Anteriormente, foi dito que um processo filho pode ser considerado um <strong>fork</strong>. Entretanto, um processo filho possuí além de <strong>fork</strong>, também a função <strong>exec</strong>, e no caso de <em>subshell</em>, também possuí outras funções. Lembrando que está sendo falado do <strong>exec de sistemas operacionais</strong>, e não do <strong>comando exec</strong> presente no <em>linux</em>.</p>
<p>O <strong>fork</strong> tem como finalidade bifurcar, ou seja, criar um processo, e executar em paralelo o restante do código que ainda não foi executado. Existem formas de fazer o processo pai esperar o processo filho terminar sua execução. Na <em>Linguagem de Programação C</em>, por exemplo, pode ser usado o <em>Wait System Call</em>. Por padrão, caso o processo pai termine, o processo filho ainda continua sua execução em <em>background</em>, se ainda não tenha sido finalizado.</p>
<p>Caso o leitor tenha o interesse de ver isso sendo executado, abaixo segue um código de exemplo de <em>fork</em> com a utilização de <em>Wait System Call</em>, para esperar a finalização do processo filho.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;wait.h&gt;
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">fork</span><span class="p">()</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Processo Filho: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">getpid</span><span class="p">());</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Processo Pai: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">getpid</span><span class="p">());</span>
<span class="p">}</span>
<span class="n">wait</span><span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="_-uma-breve-introdução-ao-exec">&gt;_ Uma breve introdução ao Exec</h2>
<p>O <strong>exec</strong>, diferentemente do <strong>fork</strong>, não cria um processo. Ele é uma funcionalidade do sistema operacional que executa um arquivo que possa ser executado, substituindo o arquivo executável já existente naquele determinado processo. Como ele não faz a criação de um novo processo, mas utiliza o processo já em execução, não há uma mudança de <strong>PID</strong>. Entretanto, todo o contexto do processo se modifica, tais como o código e os dados, pelos do novo programa em execução</p>
<p>Entendendo isso, fica mais simples do leitor entender o que o <strong>comando exec</strong> no <em>linux</em> faz.</p>
<p>Abaixo, da mesma maneira que feito com o <strong>fork</strong>, um exemplo de código utilizando-se do <strong>exec</strong>:</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Mensagem mostrada na tela. Logo abaixo, uma listagem de diretório: </span><span class="se">\n\n</span><span class="s">"</span><span class="p">);</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">args</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="s">"/usr/bin/ls"</span><span class="p">,</span> <span class="s">"-l"</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">};</span>
<span class="n">execv</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">args</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Esse texto nunca será mostrado =("</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="_-voltando-ao-comando-exec">&gt;_ Voltando ao Comando Exec…</h2>
<p>Com essa introdução à alguns conceitos de <strong>sistemas operacionais</strong>, fica mais simples explicar o que o <strong>comando exec</strong> faz. Na prática, ele faz o que foi descrito sobre o <strong>exec de sistemas operacionais</strong>.</p>
<p>Existem alguns argumentos nele que são úteis:</p>
<ul>
<li><strong>-c</strong> = É usado para executar o comando sem definir as variáveis de ambiente definidas por padrão. É mais usado para caso queira isolar e tornar mais ágil a execução, já que não há o carregamento das variáveis de ambiente.</li>
<li><strong>-l</strong> = É usado para executar o comando como um <em>shell de login</em>. Na prática, seria carregando todas as variáveis presentes nos arquivos de configuração e <em>profile</em>, assim como é feito em um <em>shell</em> convencional.</li>
<li><strong>-a</strong> = Altera o nome do comando ao qual você está executando com o <strong>comando exec</strong>. Ao digitar o comando <strong>ps</strong> ou <strong>top</strong>, verá que o processo do <strong>exec</strong> está com outro nome no comando executado.</li>
</ul>
<p>Apesar de existirem esses argumentos, eles serão usados apenas em algumas situações bem específicas. Uma das formas mais comuns do uso do <strong>comando exec</strong>, seria a utilização de <em>redirecionadores</em> e <em>descritores de arquivos</em>.</p>
<h3 id="redirecionadores">Redirecionadores</h3>
<p>Os redirecionadores de terminal, podem ser usados em conjunto com o <strong>exec</strong> para fazer com que os resultados de <strong>STDERR</strong> e <strong>STDOUT</strong> sejam ocultados. Isso permite com que execute uma série de comandos, sem obter nenhuma saída no terminal. Além disso, é possível redirecionar eles para um ou mais arquivos diferentes.</p>
<p>Existem dois símbolos principais para o uso de redirecionadores: o <strong>&gt;</strong> e o <strong>&lt;</strong>. Existem alguns outros como o <strong>&gt;&gt;</strong>, <strong>&lt;&lt;&lt;</strong>, e <strong>&lt;&lt;</strong>, entretanto, para não ficar longo este artigo, eles não serão abordados.</p>
<p>Caso queira que todas as saídas do <strong>STDOUT</strong> executados pelo <strong>exec</strong>, sejam salvas em um arquivo, execute o seguinte comando:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec</span> <span class="o">&gt;</span>/tmp/exec.log
<span class="c"># ou exec 1&gt;/tmp/exec.log</span>
</code></pre></div></div>
<p>Se deseja redirecionar dois dos descritores de arquivos padrões, o <strong>STDOUT</strong> e <strong>STDERR</strong>, redirecione o <strong>STDERR</strong>, para o <strong>STDOUT</strong>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec </span>1&gt;/tmp/exec_all.log 2&gt;&amp;1
</code></pre></div></div>
<p>Para voltar ao normal, use o comando abaixo, redirecionando a saída dos comandos para o terminal novamente:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec </span>1&gt;/dev/tty
<span class="c">#ou exec &gt;/dev/tty</span>
</code></pre></div></div>
<p>É possível também fazer o redirecionamento de todas as entradas, executando o comando abaixo:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec cat</span> &lt;/etc/passwd
</code></pre></div></div>
<h3 id="descritores-de-arquivos">Descritores de Arquivos</h3>
<p>No <em>linux</em>, existe algo que é chamado de descritores de arquivos, isso se dá ao fato de que tudo no <em>linux</em> são arquivos. Estes descritores seriam como atalhos, que permitem com que alguns recursos sejam manejados com facilidade. Com os descritores de arquivos, é possível trabalhar com a saída do terminal, entradas do teclado e abrir arquivos. Anteriormente, foi observado o seu uso nos redirecionadores. Abaixo, Será explicado um pouco como pode-se manipular esses descritores usando o <strong>comando exec</strong>.</p>
<p>Usando o <em>bash</em> como exemplo, ele normalmente trabalha com três descritores de arquivos sempre abertos:</p>
<ul>
<li>Um descritor de arquivo que serve de entrada padrão de dados</li>
<li>Um descritor de arquivo que serve de saída padrão de dados</li>
<li>Um descritor de arquivo onde as mensagens de erro são gravadas</li>
</ul>
<p>Esses descritores são definidos em <em>/usr/include/unistd.h</em> conforme a numeração abaixo:</p>
<ul>
<li><strong>0</strong> = O Descritor de arquivo 0, simboliza a entrada de dados (normalmente é o teclado).</li>
<li><strong>1</strong> = O Descritor de arquivo 1, simboliza a saída de dados (normalmente, é o terminal).</li>
<li><strong>2</strong> = O Descritor de arquivo 2, simboliza a saída de erro (normalmente, é o terminal).</li>
<li><strong>255</strong> = O Descritor de arquivo 255, é um <em>backup</em> dos descritores padrões. Ele é usado apenas caso você os modifique.</li>
</ul>
<p>Quando um processo é criado, ele herda as cópias desses descritores, que irão dizer para onde ele deve enviar, e receber, cada informação.</p>
<p>É possível redirecionar a entrada e saída (em simultâneo), criando um descritor e fazendo com que um arquivo seja criado, caso não exista:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec </span>3&lt;<span class="o">&gt;</span>arquivo_teste.txt
</code></pre></div></div>
<p>Dessa forma, é possível criar o <strong>Descritor de Arquivo de número 3</strong>, e usar ele tanto como saída para novas informações, como também como entrada das informações antigas. É importante entender que as informações inseridas após essa criação do descritor, não são lidas por ele, apenas as informações que já estavam armazenadas lá anteriormente.</p>
<p>Uma forma de fazer essa saída, seria utilizando o comando abaixo:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec </span>1&gt;&amp;3
</code></pre></div></div>
<p>Como pode ser observado no comando acima, toda vez que deseja redirecionar a saída de um descritor para outro, é necessário colocar o <strong>&amp;</strong> na frente da numeração do descritor. O código acima, redireciona o <strong>descritor 1</strong>, que no <em>bash</em> tem a sua função atrelada a saída padrão dos comandos, para o <strong>descritor 3</strong>. Com isso, a saída dos comandos serão direcionados para o <strong>descritor 3</strong>, cuja função é ler e escrever no <em>arquivo_teste.txt</em>.</p>
<p>É possível, em casos de redirecionadores de entrada, ler o que está armazenado nele:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">read</span> <span class="nt">-u</span> 3 line
<span class="nb">echo</span> <span class="nv">$line</span>
</code></pre></div></div>
<p>O comando <strong>read </strong>irá utilizar o argumento <strong>-u</strong>, cuja função é ler descritores de arquivos, permitindo com que ele leia uma linha deste descritor e armazene ela em uma variável chamada <em>line</em>. Essa é a forma mais comum de conseguir ler as entradas presentes nos descritores.</p>
<p>Outra boa prática, é sempre fechar os descritores que já foram utilizados. Assim como na programação de outras linguagens, não é bom abrir um arquivo e não fechar ele após usá-lo, também não é bom abrir um descritor de arquivo, e não fechá-lo depois. Para fechar um descritor de arquivos, utilize o seguinte comando:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec </span>3&gt;&amp;-
</code></pre></div></div>
<p>Quando se trata de descritores numéricos, para fechar sempre será usada essa sintaxe para fechá-lo: <strong>&amp;-</strong>.</p>
<p>Caso o descritor tenha outra numeração, utilize ela, ao invés do <strong>número 3</strong>. Por padrão, o limite máximo de descritores de arquivos que podem ser abertos, é de <strong>1024</strong> no <em>bash</em>. Caso queira saber o número exato em seu sistema, execute o comando:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">ulimit</span> <span class="nt">-n</span>
</code></pre></div></div>
<p>É possível também utilizar ao invés de números, algum nome de variável, como por exemplo <em>meudesc</em>. Dessa forma, é possível fazer a manipulação sem usar números diretamente. Para criar um descritor desta forma, utilize o seguinte comando:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec</span> <span class="o">{</span>meudesc<span class="o">}&gt;</span>&amp;1
</code></pre></div></div>
<p>O comando acima, fará com que todos os comandos redirecionados para o descritor <strong>{meudesc}</strong>, sejam enviados para a tela, devido ao redirecionamento do descritor criado para o <strong>descritor 1</strong>, que trata do <strong>STDOUT</strong>.</p>
<p>Caso execute o comando abaixo, ele será redirecionado para o <strong>STDOUT</strong>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">ls</span> <span class="nt">-l</span> <span class="o">&gt;</span>&amp;<span class="nv">$meudesc</span>
</code></pre></div></div>
<p>Sempre quando for usar este tipo de descritor, é necessário incluir o <strong>&amp;$</strong> no nome dele.</p>
<p>Para fechar esse tipo de descritor, basta executar o comando abaixo:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec</span> <span class="o">{</span>meudesc<span class="o">}&gt;</span>&amp;-
</code></pre></div></div>
<h3 id="outros-usos-comuns">Outros usos comuns</h3>
<p>Existem usos mais comuns do <strong>comando exec</strong> também, que não seriam a utilização de descritores de arquivos.</p>
<p>O uso mais comum, seria executar um comando e encerrar a sessão em que está, por exemplo:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec echo </span>valor
</code></pre></div></div>
<p>O comando <strong>echo</strong> será executado, e logo após encerrará a sessão do <em>bash</em> em que está.</p>
<p>É possível também mudar de <em>shell</em>, sem criar uma <em>subshell</em>, naquela sessão atual. A vantagem disso, é não ter um processo pai responsável consumindo memória:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec</span> <span class="nt">-l</span> sh
</code></pre></div></div>
<p>O exemplo acima, substitui o <em>shell</em> atual pelo <em>sh</em>.</p>
<h2 id="_-conclusão">&gt;_ Conclusão</h2>
<p>Neste artigo, foi mostrado ao leitor, o <strong>comando exec</strong>, e seus inúmeros usos. Ele é útil em manejar arquivos utilizando descritores, podendo ser usado para ler todas as linhas de um arquivo de uma forma mais eficiente do que utilizando comandos que fariam essa leitura, como o <strong>comando cat</strong>. Além disso, o leitor teve uma breve introdução de como funciona a criação de processos, e como alguns processos podem ser dependentes de outros.</p>
<p>Nem sempre um processo ser dependente de outro é uma má escolha. Cabe ao usuário decidir o que é o melhor para cada situação.</p>
<p>Gostou do artigo, tem alguma sugestão ou ficou com dúvidas? Deixe um comentário!</p>
<div class="breaker"></div></content><author><name>keven</name></author><category term="blog" /><category term="linux" /><category term="comandos" /><summary type="html">No artigo anterior desta série de artigos, o leitor obteve conhecimentos sobre o comando alias. Ele é um dos comandos embutidos no bash. Esses comandos embutidos, também conhecidos como built-in, apesar de parecerem simples, são poderosos, já que possibilitam uma comunicação mais rápida com recursos do sistema. Um desses comandos embutidos, permite com que o usuário utilize descritores de arquivos de uma forma mais prática. O comando exec, permite realizar essa manipulação, além de fazer a sua função principal: executar um novo programa no mesmo processo em que está, sem utilizar uma subshell. Neste artigo, o leitor será introduzido ao comando exec e aos conceitos de sistemas operacionais, exec e fork.</summary></entry><entry><title type="html">Comandos Linux: Alias</title><link href="https://stephan-lopes.github.io/blog/comandos-linux-alias/" rel="alternate" type="text/html" title="Comandos Linux: Alias" /><published>2022-06-28T09:00:00+00:00</published><updated>2022-06-28T09:00:00+00:00</updated><id>https://stephan-lopes.github.io/blog/comandos-linux-alias</id><content type="html" xml:base="https://stephan-lopes.github.io/blog/comandos-linux-alias/"><p><em>No artigo anterior dessa série de artigos, o leitor foi introduzido um pouco sobre Variáveis de Ambiente, e Comandos Embutidos no Bash. No linux, existem alguns comando que são próprios do terminal. Esses comandos permitem realizar tarefas administrativas, ou então, tarefas que possibilitam manejar a forma como pode ser trabalhado com o bash. Neste artigo, o leitor será introduzido a conhecer um dos comandos built-in do linux: o alias.</em></p>
<h2 id="_-o-comando-alias">&gt;_ O Comando Alias</h2>
<p>O comando <strong>alias</strong>, é um comando embutido do <em>bash</em> que permite escrever atalhos de comandos, facilitando assim, o uso de comandos grandes/complexos no dia-a-dia. Algumas distribuições <strong>linux</strong> já possuem alguns <strong>alias</strong> configurados. Um deles, que pode ser citado é o <strong>ll</strong>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># caso o alias não tenha sido definido pela distribuição que está usando, copie o comando, e cole no terminal</span>
<span class="nb">alias </span><span class="nv">ll</span><span class="o">=</span><span class="s1">'ls -l'</span>
</code></pre></div></div>
<p>Quando um <strong>alias</strong> é definido, ele permite com que usando o atalho, neste caso o <strong>ll</strong>, seja executado na verdade o comando <strong>ls -l</strong>.</p>
<p>Para visualizar todos os <strong>alias</strong> presentes na sessão atual do <em>bash</em>, execute o comando <strong>alias</strong> sem nenhum argumento.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">alias</span>
</code></pre></div></div>
<h2 id="_-o-que-vem-primeiro-o-comando-ou-o-atalho">&gt;_ O que vem primeiro: o comando ou o atalho?</h2>
<p>Toda vez que um comando é digitado no <em>bash</em>, é feito primeiro a checagem se o comando possuí um atalho. Se ele possuir, então ele é executado. Caso ele não possua, é feita a verificação se aquele comando existe.</p>
<p>Para fazer o teste, o leitor pode definir um <strong>alias</strong> para um comando com o nome <strong>cd</strong>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">alias cd</span><span class="o">=</span><span class="s2">"echo acho que não mudou de diretorio :</span><span class="se">\(</span><span class="s2">"</span>
</code></pre></div></div>
<p>Ao digitar o comando <strong>cd</strong>, o texto do comando <strong>echo</strong> será escrito ao invés de navegar entre diretórios, como deveria fazer o comando <strong>cd</strong>.</p>
<p>Isso acontece porque o <em>bash</em>, antes de executar um comando, faz a leitura do texto enviado pelo terminal, para então, posteriormente, executá-lo. Para melhor entendimento, o fluxo abaixo mostra a ordem de execução de um comando no <em>bash</em>:</p>
<ul>
<li>Bash faz a leitura do comando digitado</li>
<li>Bash verifica se existe algum alias em tempo de leitura do comando</li>
<li>Bash passa para a fase de execução</li>
<li>Bash executa o comando, se ele estiver presente no $PATH</li>
</ul>
<p>Quando ele encontra algum atalho de comando na fase de leitura do comando digitado, ele faz a substituição deste atalho na fase de execução. Caso o <strong>alias</strong> seja um atalho de um atalho, ele executa a conversão até chegar a um comando. Se o fim desse <strong>alias</strong> não for um comando, ou for um comando que não está presente no <strong>PATH</strong>, ele dará erro em tempo de execução, informando que o comando não existe.</p>
<h2 id="_-criando-um-alias">&gt;_ Criando um Alias</h2>
<p>A sintaxe de uso do comando <strong>alias</strong>, não é complicado, mas simples. É possível criar um <strong>alias</strong> seguindo o molde abaixo:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">alias </span><span class="nv">COMANDO_ATALHO</span><span class="o">=</span><span class="s2">"COMANDO_ORIGINAL"</span>
</code></pre></div></div>
<p>O <em>COMANDO_ORIGINAL</em> pode ser colocado entre <em>aspas duplas</em>, <em>simples</em>, e <em>crase</em>, permitindo definir <em>flags</em>, e argumentos. O <em>COMANDO_ATALHO</em> não pode conter <strong>/</strong>, <strong>$</strong>, <strong>`</strong>, e <strong>=</strong>. Além disso, todo o argumento a mais passado para o comando de atalho, é redirecionado como um argumento do comando original. Em casos que isso não é algo desejado, adicione <strong>;</strong> no final do <strong>alias</strong>, para que novos argumentos sejam entendidos como comandos, e não como um argumento do comando executado pelo <strong>alias</strong>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">alias </span><span class="nv">la</span><span class="o">=</span><span class="s2">"ls -la;"</span>
</code></pre></div></div>
<p>Se o <strong>alias</strong> acima for executado passando algum argumento a ele, o argumento será executado como comando.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>la <span class="nt">-R</span> <span class="c"># O alias *la* será interpretado, mas o -R será tratado como se fosse um comando, então, irá falhar.</span>
</code></pre></div></div>
<p>Também é importante definir um valor ao <strong>alias</strong>. Se nenhum valor for definido para o comando de atalho, ele não será criado.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">alias </span>lf <span class="c"># Se o usuário digitar **lf** no terminal, será informado que o comando não existe.</span>
</code></pre></div></div>
<p>Algo que é incomum, mas possível, é a criação de um <strong>alias</strong> que tem um <strong>alias</strong> como seu comando.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">alias </span><span class="nv">rmi</span><span class="o">=</span><span class="s2">"rm -i"</span>
<span class="nb">alias </span><span class="nv">rrm</span><span class="o">=</span><span class="s2">"rmi -r"</span>
</code></pre></div></div>
<p>Se executar o comando <strong>rrm</strong> ele irá interpretar o <strong>alias</strong> <strong>rmi</strong> passando o <strong>-r</strong> como argumento, que executará o comando <strong>rm -i -r</strong>.</p>
<h2 id="_-criando-um-alias-global">&gt;_ Criando um Alias Global</h2>
<p>Para realizar a criação de um <strong>alias</strong> que possa ser usado entre sessões, será necessário definir ele em um arquivo. O arquivo, no caso do <em>bash</em>, seria um dos arquivos descritos abaixo:</p>
<ul>
<li>~/.bashrc</li>
<li>~/.bash_profile</li>
<li>~/.profile</li>
<li>~/.bash_login</li>
<li>/etc/profile</li>
<li>/etc/profiles.d/*</li>
<li>/etc/bash.bashrc</li>
<li>/etc/bashrc</li>
</ul>
<p>Se deseja apenas que o <strong>alias</strong> esteja em uso em sessões do <em>shell</em> que sejam efetuados <em>login</em> via <em>console</em>, ou então via <strong>SSH</strong>, defina o <strong>alias</strong> em arquivos <strong>profile</strong>, já que eles são carregados em <em>shells de login</em> somente.</p>
<p>Caso queira apenas que o usuário atual tenha o <strong>alias</strong>, defina em um dos arquivos ocultos na <strong>HOME</strong> do usuário. Ou, se preferir tornar global, ao ponto de que todos os usuários tenham determinado <strong>alias</strong>, defina-o em algum dos arquivos que esteja no diretório <strong>/etc</strong>. e presentes na lista acima.</p>
<h2 id="_-removendo-um-alias">&gt;_ Removendo um Alias</h2>
<p>Quando cria um <strong>alias</strong>, é possível que tenha o desejo depois de removê-lo. O comando <strong>unalias</strong> pode ser usado para realizar essa remoção:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">unalias rm</span>
</code></pre></div></div>
<p>Assim como o <strong>alias</strong> executado no terminal, ele é apenas definido na sessão atual. Se precisar remover um <strong>alias</strong> definido para todas as sessões, a melhor alternativa é descobrir onde ele está sendo definido, e então removê-lo do arquivo. Caso isso não seja possível, pode ser informado em um dos arquivos acima (dependendo de seu uso) o comando <strong>unalias</strong> e o nome de seu atalho.</p>
<h2 id="_-conclusão">&gt;_ Conclusão</h2>
<p>Neste artigo, o leitor obteve informações de como visualizar, criar, gerenciar, e remover atalhos para comandos existentes no sistema. Esses atalhos são poderosos, podendo agilizar o dia-a-dia de quem trabalha com <strong>linux</strong>, a medida que necessita cada vez mais usar argumentos e <em>flags</em> em determinados comandos. No próximo artigo, o leitor será introduzido a outro comando built-in poderoso: o comando exec.</p>
<div class="breaker"></div></content><author><name>keven</name></author><category term="blog" /><category term="linux" /><category term="comandos" /><summary type="html">No artigo anterior dessa série de artigos, o leitor foi introduzido um pouco sobre Variáveis de Ambiente, e Comandos Embutidos no Bash. No linux, existem alguns comando que são próprios do terminal. Esses comandos permitem realizar tarefas administrativas, ou então, tarefas que possibilitam manejar a forma como pode ser trabalhado com o bash. Neste artigo, o leitor será introduzido a conhecer um dos comandos built-in do linux: o alias.</summary></entry><entry><title type="html">Comandos Linux: Variáveis de Ambiente</title><link href="https://stephan-lopes.github.io/blog/comandos-linux-variaveis-de-ambiente/" rel="alternate" type="text/html" title="Comandos Linux: Variáveis de Ambiente" /><published>2022-06-13T21:00:00+00:00</published><updated>2022-06-13T21:00:00+00:00</updated><id>https://stephan-lopes.github.io/blog/comandos-linux-variaveis-de-ambiente</id><content type="html" xml:base="https://stephan-lopes.github.io/blog/comandos-linux-variaveis-de-ambiente/"><p><em>Assim como existem alguns comandos que podem ser usados no Shell, também existem variáveis que podem ser definidas pelo sistema, ou pelo usuário. Essas variáveis, podem ser utilizadas dentro de programas, pelo usuário ou pelo sistema. Elas são mais conhecidas como variáveis de ambiente. Neste artigo, o leitor será introduzido desde a criação de uma variável de ambiente, como a utilização da mesma. Também serão mostradas algumas variáveis de ambiente embutidos no <strong>Bash</strong> (o shell usado como base), o que é uma subshell, além de comandos embutidos.</em></p>
<h2 id="_-o-que-é-uma-variável-e-uma-constante">&gt;_ O que é uma Variável e uma Constante?</h2>
<p>No <strong>Bash</strong>, assim como nas <strong>linguagens de programação</strong>, existem variáveis. Variáveis nada mais são do que espaços na memória de um determinado computador destinados a armazenar dados, que podem ser alterados durante a execução do programa. O que as difere de constantes, é que as variáveis podem ser alteradas. Já as contantes, não podem ter seu valor modificado após a sua declaração.</p>
<p>Caso esse termo pareça novo para o leitor, uma analogia com um produto qualquer no mundo em que vive, pode auxiliar no entendimento. Imagine a seguinte situação: Você vai até um supermercado em uma determinada data, vê o preço de um suco de 2L de laranja por R$ 10,00. No ano seguinte, você vai no mesmo supermercado, e vê o mesmo suco, da mesma marca, por R$ 12,00. Pode-se extrair dois valores para a analogia: O suco de laranja, e o preço dele.</p>
<p>O suco, pode ser comparado com uma constante. Ele não mudou, seus ingredientes não são diferentes, e ainda continua tendo mesma embalagem e marca. Já o preço, é algo que pode ser mudado, tanto que o suco de R$ 10,00, virou R$ 12,00. Sendo assim, o preço deste suco, pode ser comparado com uma variável. Se mudar uma contante, assim como mudar os ingredientes de um suco de laranja, estará transformando aquele endereço na memória, em outro. No caso do suco, estaria transformando ele em outro produto!</p>
<p>O mesmo não acontece quando o preço daquele produto se modifica. O endereço (o suco de laranja), continua sendo o mesmo. Só mudou o seu valor(preço).</p>
<h2 id="_-declarando-uma-variável-no-bash">&gt;_ Declarando uma variável no Bash</h2>
<p>Para realizar a declaração de uma variável no <strong>Bash</strong>, use a seguinte sintaxe:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">nome_da_variavel</span><span class="o">=</span>valor_da_varivavel
</code></pre></div></div>
<p>Os nomes das variáveis são limitados a caracteres alfanuméricos. Como visto acima, não pode existir espaço entre o <em>nome da variável</em> e o <em>valor</em> dela. O uso de espaço só é permitido no valor da variável quando utiliza-se algo chamado <em>quoting</em>. Isso será melhor explicado em outros artigos, mas em resumo, é permitido usar espaço quando o texto é envolto por aspas duplas ou simples.</p>
<p>Para ler o conteúdo armazenado na variável, use o comando embutido do <strong>bash</strong>, <strong>echo</strong>. Usando o comando, em conjunto com a variável, pode ser visualizado o seu valor. Por exemplo:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="nv">$nome_da_variavel</span>
</code></pre></div></div>
<p>Entretanto, essa variável está limitada para a <em>sessão</em> em que está no <strong>Bash</strong>. Caso abra uma nova <em>sessão</em>, e tente executar o mesmo comando, o valor declarado na variável anteriormente não vai ser mostrado na tela. Veja também que para usar uma variável, deve ser colocado um <strong>$</strong> na frente do nome dela.</p>
<h2 id="_-o-que-são-sessões-no-bash">&gt;_ O que são sessões no Bash?</h2>
<p>O <strong>Bash</strong>, é composto por <em>sessões</em>. Cada <em>sessão</em> possuí suas variáveis de ambiente. Existem <em>sessões</em> que estão dentro de <em>sessões</em>, elas são chamadas de <em>subsessões</em> ou subshell. Elas podem ser usadas para executar pequenos comandos com algum retorno, por exemplo, e serem concatenados em um outro comando.</p>
<p>Toda vez que um script shell é executado, ele cria um subshell, um shell filho deste shell.</p>
<p>Para criar, você pode escrever algum comando entre parenteses <strong>()</strong>, ou entre crase. Em alguns casos, será necessário a inclusão de um <strong>$</strong> antes dos parenteses. Um exemplo:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Executando com $()</span>
<span class="nv">VAR</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo </span>valor<span class="si">)</span>
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Executando com crase ``</span>
<span class="nv">VAR</span><span class="o">=</span><span class="sb">`</span><span class="nb">echo </span>valor<span class="sb">`</span>
</code></pre></div></div>
<p>Em palavras mais simples, um subshell, é um processo filho deste shell principal. Caso abra uma nova <em>sessão</em> do <strong>bash</strong>, dentro dessa em que está, e não exporte as variáveis de ambiente, você não irá conseguir ler o valor desta variável:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">VAR</span><span class="o">=</span>1
bash
<span class="nb">echo</span> <span class="nv">$VAR</span>
</code></pre></div></div>
<p>Para que consiga ler o valor dessa variável dentro destes shells, é necessário incluir o comando embutido <strong>export</strong> antes da variável. O seguinte comando irá funcionar:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">VAR</span><span class="o">=</span>1
bash
<span class="nb">echo</span> <span class="nv">$VAR</span>
</code></pre></div></div>
<h2 id="_-variáveis-pré-definidas-e-dinâmicas-no-bash">&gt;_ Variáveis pré-definidas e dinâmicas no Bash</h2>
<p>O Bash possuí algumas variáveis pré-definidas, que podem ser de grande auxilio para o usuário. As principais seriam:</p>
<ul>
<li><strong>DISPLAY</strong> = Ele define qual o display deve exibir suas janelas</li>
<li><strong>HISTFILE</strong> = Caminho para o histórico de comandos do usuário</li>
<li><strong>HISTFILESIZE</strong> = Quantidade de linhas/comandos que podem ser armazenados no arquivo de histórico</li>
<li><strong>HOME</strong> = Caminho para o diretório <em>home</em> do usuário</li>
<li><strong>PATH</strong> = Diretório em que o Linux irá procurar por arquivos executáveis</li>
<li><strong>PS1</strong> = Aparência do seu Terminal (Prompt de Comando)</li>
<li><strong>PWD</strong> = Diretório atual</li>
<li><strong>OLDPWD</strong>= Diretório que estava anteriormente.</li>
<li><strong>TERM</strong> = Terminal que está aberta a <em>sessão</em></li>
<li><strong>LOGNAME</strong> = Nome do usuário atual</li>
</ul>
<p>Além dessas variáveis, existe também algumas variáveis que são definidas dinamicamente no shell. As principais seriam:</p>
<ul>
<li><strong>$$</strong> = Mostra o PID do Shell Atual (PID seria um número que identifica o processo)</li>
<li><strong>$!</strong> = Mostra o PID do último processo executado</li>
<li><strong>$?</strong> = Mostra o código de retorno do último processo/comando executado, sendo o codigo <strong>0</strong> como sucesso.</li>
<li><strong>~</strong> = Corresponde ao diretório <em>home</em> do usuário.</li>
<li><strong>~root</strong> = Corresponde ao diretório <em>home</em> do usuário <strong>root</strong>.</li>
</ul>
<p>Essas variáveis embutidas atuam quase como comandos, já que devolvem valores que podem ser especialmente úteis até mesmo em scripts.</p>
<h2 id="_-comandos-embutidos-no-bash">&gt;_ Comandos Embutidos no Bash</h2>
<p>Além de variáveis, existem alguns comandos embutidos no <strong>Bash</strong>. Alguns deles, inclusive, já foram mostrados. Os principais comandos embutidos no bash seriam:</p>
<ul>
<li><strong>alias</strong> = Cria um alias (nome alternativo) para um comandos</li>
<li><strong>exec</strong> = Executa um comando em uma nova <em>sessão</em> do shell</li>
<li><strong>echo</strong> = Joga para a saída, um texto replicado, ou uma variável</li>
<li><strong>env</strong> = Sem argumentos, exibe as variáveis de ambientes, e os seus valores</li>
<li><strong>export</strong> = Define uma variável de ambiente para a <em>sessão</em>, e para todas as <em>sessões</em> filhas dessa</li>
<li><strong>pwd</strong> = Mostra o diretório atual</li>
<li><strong>set</strong> = Define o valor de uma variável. Quando não usado com argumentos, exibe as variáveis já definidas</li>
<li><strong>unset</strong> = Remove uma variável da <em>sessão</em> do <strong>bash</strong></li>
</ul>
<h2 id="_-conclusão">&gt;_ Conclusão</h2>
<p>Neste artigo, o leitor teve um resumo sobre variáveis de ambiente, bem como, sobre alguns comandos embutidos no shell. Nos próximos artigos, será mostrado um pouco mais sobre esses comandos, mostrando como podem ser usados na prática.</p>
<div class="breaker"></div></content><author><name>keven</name></author><category term="blog" /><category term="linux" /><category term="comandos" /><summary type="html">Assim como existem alguns comandos que podem ser usados no Shell, também existem variáveis que podem ser definidas pelo sistema, ou pelo usuário. Essas variáveis, podem ser utilizadas dentro de programas, pelo usuário ou pelo sistema. Elas são mais conhecidas como variáveis de ambiente. Neste artigo, o leitor será introduzido desde a criação de uma variável de ambiente, como a utilização da mesma. Também serão mostradas algumas variáveis de ambiente embutidos no Bash (o shell usado como base), o que é uma subshell, além de comandos embutidos.</summary></entry><entry><title type="html">Comandos Linux: A linha de Comando</title><link href="https://stephan-lopes.github.io/blog/comandos-linux-a-linha-de-comando/" rel="alternate" type="text/html" title="Comandos Linux: A linha de Comando" /><published>2022-06-09T20:00:00+00:00</published><updated>2022-06-09T20:00:00+00:00</updated><id>https://stephan-lopes.github.io/blog/comandos-linux-a-linha-de-comando</id><content type="html" xml:base="https://stephan-lopes.github.io/blog/comandos-linux-a-linha-de-comando/"><p><em>No linux, temos um espaço, onde podemos conversar com recursos que são gerenciados pelo nosso sistema operacional, além de ter a possibilidade de usar ferramentas que podem nos auxiliar no dia-a-dia. Esse espaço se chama <strong>Terminal</strong>. Esse é o primeiro artigo de uma série de postagens abordando como funciona a linha de comando no linux, bem como mostrar os comandos essênciais que devem ser conhecidos pelo administrador desse sistema. Eles podem ser aproveitados por qualquer pessoa que deseja conhecer mais sobre linux</em>.</p>
<h2 id="_-o-que-é-um-sistema-operacional">&gt;_ O que é um Sistema Operacional?</h2>
<p>Poderia começar de uma forma sem abordar isso, mas, é sempre bom contextualizar o que é um <em>Sistema Operacional</em>, afinal, o <a href="https://www.linux.org/">Linux</a> é um deles. Existem hoje, diversos <em>Sistemas Operacionais</em>, tais como Unix, macOS, BSD, Minix, <a href="https://www.linux.org">Linux</a>, Solaris, e por ai vai. O que eles tem em comum? Todos eles possuem duas funções principais (e diria eu, essênciais), que seriam:</p>
<ul>
<li><strong>Fornecer a programadores, um conjunto de recursos mais simples de serem manipulados ao invés de recursos abstratos e confusos do hardware.</strong></li>
<li><strong>Gerenciar os recursos do hardware</strong></li>
</ul>
<p>Em outras palavras, sendo elas bem resumidas, um <em>sistema operacional</em> é o responsável por fazer uma interface entre o usuário e o hardware do computador.</p>
<p>O <a href="https://www.linux.org">Linux</a>, não é um <em>Sistema Operacional</em> completo, diferente de como a maioria das pessoas imagina. Ele é somente o <strong>Kernel</strong>. Ele faz as duas funções importantes, abordadas anteriormente. Porém, quem dá “vida” ao <em>Sistema Operacional</em>, são as distribuições, que vem com algumas interfaces de iteração com a máquina, sendo ela via texto ou gráfica, e também programas. Estes três pontos: <strong>Kernel</strong>, <strong>Interface com Usuário</strong>, e <strong>Programas</strong>, em conjunto, podem ser definidos como um <em>Sistema Operacional</em>.</p>
<h2 id="_-quer-dizer-que-o-kernel-é-algo-inútil">&gt;_ Quer dizer que o Kernel é algo inútil?</h2>
<p>Claro que não! Sem ele, não existe esse gerenciamento e nem mesmo a abstração entre o usuário e seu hardware. Ele é algo que não interagimos diretamente, mas que existe no núcleo de seu <em>sistema operacional</em>. Sem ele, as distribuições linux não existiriam.</p>
<p>Quando trabalhamos em uma linha de comando no <a href="https://www.linux.org">linux</a>, também conhecido como <strong>SHELL</strong>, estamos utilizando um programa, que pode manipular recursos do sistema, mas que ainda sim, não está no mesmo nível que o <strong>Kernel</strong>.</p>
<h2 id="_-o-shell">&gt;_ O Shell</h2>
<p>O <strong>Shell</strong>, nada mais é do que uma interface, um interpretador de comandos. Nele, podemos executar scripts, e utilizar uma série de comandos para manusear o sistema, seja modificando algum componente importante, ou apenas utilizando ele como “ponte” para abrir um editor de texto.</p>
<p>Abordaremos o <strong>Shell</strong> conhecido como <strong>BASH</strong>(<em>Bourne-Again SHell</em>). Existem outros milhares de <strong>Shell</strong>, como o <strong>ZSH</strong>, <strong>SH</strong>, <strong>CSH</strong>, <strong>KSH</strong>, etc. Cada um tem sua particularidade, como por exemplo o <strong>CSH</strong> que permite o uso da <em>linguagem C</em>, de forma iterativa, e de <strong>Shell Script</strong>. Caso queira saber qual <strong>Shell</strong> está utilizando, execute o comando:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">echo</span> <span class="nv">$SHELL</span> </code></pre></figure>
<p>Esse comando irá informar qual <strong>shell</strong> você está usando. O <strong>Shell</strong> em uso, é armazenado na variável de ambiente <strong>$SHELL</strong>.</p>
<h2 id="_-comando-o-que-é-isso">&gt;_ Comando? O que é isso?</h2>
<p>Um comando é algo que você executa dentro do terminal, que retorna algum resultado para você, mostrando, ou não, na tela, o seu resultado. Existem três tipos de comandos:</p>
<ul>
<li><strong>Comando Interno do Shell(built-in)</strong></li>
<li><strong>Binários localizados no PATH</strong></li>
<li><strong>Scripts(sequência lógica de instruções interpretadas pelo Shell)</strong></li>
</ul>
<p>Podemos definir que um programa também seja um comando. Não vemos ele sendo executado quando abrimos via interface gráfica, mas ele é utilizado toda a vez que abrimos um programa, como por exemplo, um navegador.</p>
<h2 id="_-conclusão">&gt;_ Conclusão</h2>
<p>Neste artigo, foi abordado um pouco sobre o que é um <em>sistema operacional</em>, para contextualizar a utilidade do uso de linhas de comando no <a href="https://www.linux.org">linux</a>. Também, houve uma introdução sobre o que é um <strong>Shell</strong>, e o que é um comando. Nos próximos artigos, iremos falar um pouco mais sobre eles, e introduzir o leitor às variáveis de ambiente.</p>
<div class="breaker"></div></content><author><name>keven</name></author><category term="blog" /><category term="linux" /><category term="comandos" /><summary type="html">No linux, temos um espaço, onde podemos conversar com recursos que são gerenciados pelo nosso sistema operacional, além de ter a possibilidade de usar ferramentas que podem nos auxiliar no dia-a-dia. Esse espaço se chama Terminal. Esse é o primeiro artigo de uma série de postagens abordando como funciona a linha de comando no linux, bem como mostrar os comandos essênciais que devem ser conhecidos pelo administrador desse sistema. Eles podem ser aproveitados por qualquer pessoa que deseja conhecer mais sobre linux.</summary></entry><entry><title type="html">Assinatura de Commits com GPG</title><link href="https://stephan-lopes.github.io/blog/assinaturas-de-commits-com-gpg/" rel="alternate" type="text/html" title="Assinatura de Commits com GPG" /><published>2022-04-29T23:00:00+00:00</published><updated>2022-04-29T23:00:00+00:00</updated><id>https://stephan-lopes.github.io/blog/assinaturas-de-commits-com-gpg</id><content type="html" xml:base="https://stephan-lopes.github.io/blog/assinaturas-de-commits-com-gpg/"><p><em>No Git, toda vez que é feito um commit, ele coleta seu usuário e seu e-mail, e anexa em um Commit. Entretanto, ele pode ser manipulado, e alguém pode se passar por você. Sendo assim, o ideal é assinar seus commits com chave GPG. Com ela, você consegue comprovar que você é você, para todos aqueles que possuem uma chave pública da chave privada que só você possuí. Este tutorial, é um guia de configuração, bem como a demonstração do problema em si, e em como resolvê-lo. Espero que gostem, e coloquem em prática as dicas!</em></p>
<h2 id="_-o-problema-do-commit-sem-assinatura">&gt;_ O Problema do Commit Sem Assinatura</h2>
<p>Em um ambiente de produção, o Commit sem assinatura é muito mais comum que o Commit com assinatura. Por isso, é importante que você configure o GPG para assinar seus commits. Essa, digamos, má pratica, abre brechas que podem ser exploradas, caso seus commits não sejam assinados. Vou mostrar um exemplo.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/assinatura-de-commits-com-gpg/5496900581142.png" alt="Imagem" /></p>
<p>Quando adiciono um arquivo em um projeto e faço um <em>git commit</em>, o git não assina o commit por padrão. Dessa forma, ele acaba pegando a variável <strong>user.name</strong> e <strong>user.email</strong>, que são definidas com os seguintes comandos:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">git config <span class="nt">--global</span> user.name <span class="s2">"Seu Nome"</span>
git config <span class="nt">--global</span> user.email <span class="s2">"email@teste.com"</span></code></pre></figure>
<p>Quando enviado por push, ele não valida se essas informações são verdadeiras ou não. Ou seja, quem vê dentro de um repositório, não sabe se realmente foi aquela pessoa que fez aquele commit.</p>
<p>Pra demonstrar isso, vamos criar um arquivo, e fazer um commit com outro usuário e e-mail, usando o seguinte código para isso:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">git commit <span class="nt">--author</span><span class="o">=</span><span class="s2">"Mark Zuckerberg marquinho@teste.com"</span> <span class="nt">-m</span> <span class="s2">"Teste de commit"</span></code></pre></figure>
<p>Após confirmarmos o Commit, temos esse resultado:</p>
<p><img src="https://stephan-lopes.github.io/assets/images/assinatura-de-commits-com-gpg/6636094248085.png" alt="Imagem" /></p>
<p>Talvez você diga: <em>“Mas Keven… Isso é em ambiente local, não vai acontecer nada se você colocar ele em um repositório do github.”</em></p>
<p>Se pensou isso, sinto lhe dizer, mas está enganado. Olha o que acontece quando envio por push esses commits:</p>
<p><img src="https://stephan-lopes.github.io/assets/images/assinatura-de-commits-com-gpg/9114529757421.png" alt="Imagem" /></p>
<p>Preocupante, não? Mas calma, vamos resolver isso.</p>
<h2 id="_-gerando-uma-chave-gpg">&gt;_ Gerando uma Chave GPG</h2>
<p>O primeiro passo para conseguirmos assinar nossos commits, é gerar uma chave GPG. Tenha certeza de que a sua máquina tem o GPG instalado. Usaremos a <strong>versão 2.2.19</strong>, nesse tutorial, mas você pode usar qualquer versão (preferencialmente &gt;= 2).</p>
<p>Para instalar, vamos usar o comando abaixo em um Ubuntu linux (em outro SO, como Windows ou Unix, sugiro procurar na documentação do github):</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">sudo </span>apt <span class="nb">install </span>gnupg</code></pre></figure>
<p>Após a instalação, vamos criar uma chave GPG, utilizando o comando abaixo:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gpg <span class="nt">--full-generate-key</span></code></pre></figure>
<p>Após a execução do comando, ele irá realizar a geração de uma chave GPG. Selecione o tipo de chave (no tutorial usaremos a <strong>RSA and RSA</strong>), e dê enter.</p>
<p>Feito isso, será perguntado o tamanho da chave em bits. Para uma maior segurança, usaremos o tamanho de <strong>4096 bits</strong>.</p>
<p>Será então solicitado que informe o número de dias que a chave deve permanecer viva. Se você não informar nada, a chave ficará viva por 0 dias, ou seja, para sempre. No tutorial, usaremos uma chave com validade de <strong>0 dias</strong>. Nesse caso, quando é definido 0 dias, irá ser questionado se tem realmente certeza que quer criar uma chave com uma validade tão longa. <strong>Confirme e dê enter</strong>.</p>
<p>Por fim, insira o <strong>nome</strong>, e o <strong>endereço de e-mail</strong> que deseja vincular a chave. O endereço de e-mail, pode ser de dois tipos:</p>
<ul>
<li>Um endereço de e-mail pessoal, registrado na sua conta do GitHub.</li>
<li>Ou, o mais indicado, um endereço de e-mail no-reply, que é gerado pelo GitHub.</li>
</ul>
<p>Caso opte pela segunda opção, você pode entrar no site do GitHub e verificar este endereço de e-mail no-reply. Pra fazer isso, em seu <strong>Perfil</strong>, acesse <strong>Settings</strong>, posteriormente, acesse <strong>Emails</strong>, e por fim, marque a caixa onde está escrito <strong>Keep my email addresses private</strong>. Dentro dela, você pode obter esse endereço de e-mail no-reply.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/assinatura-de-commits-com-gpg/6096521027427.png" alt="Imagem" /></p>
<p>Este endereço, dependendo de quando criou sua conta, pode mudar. Quem criou em 2017, pode ter um endereço de e-mail no-reply diferente, sem aqueles números antes do <strong>+</strong>. Essa é a forma mais indicada, para evitar que deixe exposto seu e-mail, publicamente. Em casos que deseja deixar exposto, a primeira opção será a mais ideal.</p>
<p>No meu caso, o e-mail no-reply é <strong>40838038+stephan-lopes@users.noreply.github.com</strong>. Após informar o endereço de e-mail, você pode adicionar algum comentário, ou <strong>deixar em branco</strong>.</p>
<p>Será então solicitado para confirmar. Para isso, digite a letra <strong>o</strong> e dê enter. Depois disso, você precisará informar a <strong>Passphrase</strong>, que seria como uma senha. Informe a <strong>Passphrase</strong> e dê enter. Use o mouse, ou o teclado, para que a chave seja gerada, e pronto! Ela foi gerada e agora está em seu ambiente!</p>
<h2 id="_-colocando-a-chave-publica-na-conta-do-github">&gt;_ Colocando a Chave Publica na Conta do GitHub</h2>
<p>Com a chave gerada, precisamos inserir ela no Github. Precisamos fazer isso, por que o GitHub precisa validar se a chave realmente é sua. Se não, nada impediria você também de gerar uma chave, como fizemos anteriormente, informando um e-mail, que não é seu, e, se passando por essa pessoa, fazer um commit.</p>
<p>Vamos precisar da chave pública, então, utilize o comando abaixo:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gpg <span class="nt">--list-secret-keys</span> <span class="nt">--keyid-format</span><span class="o">=</span>long</code></pre></figure>
<p>Esse comando listará todas as chaves que estão armazenados no agent. Você precisará encontrar uma chave que tenha o <strong>keyid</strong> que você gerou. Esse <strong>keyid</strong>, seria o código de letras depois do <strong>rsa4096/</strong>, por exemplo.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/assinatura-de-commits-com-gpg/8207360680388.png" alt="Imagem" /></p>
<p>Copie esse código, e execute o seguinte comando abaixo, para ter acesso a chave pública:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gpg <span class="nt">--armor</span> <span class="nt">--export</span> FF79A185C539E72E</code></pre></figure>
<p>Copie a chave pública, fornecida como saída do comando e acesse o GitHub. Na página de configuração da conta, na seção <strong>SSH and GPG Key</strong>, e depois, na seção <strong>GPG Key</strong>, clique em <strong>New GPG Key</strong>. <strong>Coloque a chave pública</strong>, e depois, clique em <strong>Add GPG Key</strong>. Forneça sua senha do GitHub para concluir.</p>
<h2 id="_-configurando-endereço-de-e-mail-localmente">&gt;_ Configurando Endereço de E-mail Localmente</h2>
<p>Agora que a chave foi inserida no GitHub, precisamos configurar o endereço de e-mail localmente. Lembra do endereço de e-mail no-reply que você gerou? Este endereço é o endereço que será usado aqui, e será atrelado aos seus commits.</p>
<p>Para concluir, use o seguinte comando:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">git config <span class="nt">--global</span> user.email <span class="s2">"COLOQUE AQUI SEU ENDEREÇO DE EMAIL AQUI"</span></code></pre></figure>
<p>Isso irá mudar globalmente. Se você quiser mudar apenas para o repositório atual, use o comando sem a opção <strong>–global</strong>.</p>
<h2 id="_-configurando-assinatura-em-ambiente-local">&gt;_ Configurando Assinatura em Ambiente Local</h2>
<p>Mesmo com todas essas configurações, a ferramenta git ainda não sabe que deve assinar todos os commits. Lembra do que eu disse no inicio, em que isso não é feito por padrão?</p>
<p>Caso queira assinar um commit, até o momento, você teria que adicionar a flag <strong>-S</strong> no comando <em>git commit</em>.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">git commit <span class="nt">-S</span> <span class="nt">-m</span> <span class="s2">"Mensagem de commit"</span></code></pre></figure>
<p>Entretanto, essa forma é uma forma um pouco “custosa”. Isso, porque, a cada vez que precise fazer um commit, terá que lembrar de adicionar a Flag. Outro problema que podemos identificar também, é que não definimos para a ferramenta, qual chave ela deve utilizar. Imagine que tenhamos 10 chaves GPG. Como o git saberá qual chave deve ser usada?</p>
<p>E os problemas não acabaram por ai… Como o GPG irá perguntar a palavra passe? Por padrão, ele não sabe para qual tty ele deve perguntar isso!</p>
<p>Então, mesmo tentando fazer essa assinatura manualmente, você iria se deparar com o seguinte erro:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>git commit <span class="nt">-S</span> <span class="nt">-m</span> <span class="s2">"...."</span>
error: gpg failed to sign the data
fatal: failed to write commit object</code></pre></figure>
<p>Precisamos resolver esses problemas. Vamos primeiro informar o git sobre qual a chave que deve ser utilizada. Busque o <strong>keyid</strong>, como feito anteriormente:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gpg <span class="nt">--list-secret-keys</span> <span class="nt">--keyid-format</span><span class="o">=</span>long</code></pre></figure>
<p>E depois, informe ele no seguinte comando (<em>Troque o FF79A185C539E72E pelo seu keyid.</em>):</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">git config <span class="nt">--global</span> user.signingkey FF79A185C539E72E</code></pre></figure>
<p>Feito! Agora, todos os commits assinados que você fizer, serão assinados com a chave que você definiu!</p>
<p>Entretanto, o git ainda não faz isso de forma automática. Ele ainda espera que você informe a flag <strong>-S</strong> no comando <em>git commit</em>. Para mudar isso, use o comando abaixo:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">git config <span class="nt">--global</span> commit.gpgsign <span class="nb">true</span></code></pre></figure>
<p>Com isso, cada vez que executar um <em>git commit</em>, o git irá assinar o commit de forma automática, sem você precisar adicionar a flag <strong>-S</strong>.</p>
<p>O último passo, é definir nosso TTY, para que o GPG possa perguntar a palavra passe. Caso contrário, teremos aquele erro na hora que formos assinar o commit, por não fornecermos a palavra passe. Execute o comando abaixo, em seu <strong>~/.bashrc</strong>:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">echo</span> <span class="s1">'export GPG_TTY=$(tty)'</span> <span class="o">&gt;&gt;</span> ~/.bashrc</code></pre></figure>
<p>Caso esteja usando outro terminal que não seja o bash, use o arquivo apropriado para ele. Uma outra observação a ser feita, é em casos de uso com o zsh, utilizando fontes Powerlevel10k. Copie o export acima para o arquivo .zshrc, antes do Powerlevel. Caso contrário, isso não irá funcionar.</p>
<p>Abra uma nova sessão, ou então, execute o comando abaixo no terminal, para que isso já se torne válido na sessão atual:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">source</span> ~/.bashrc</code></pre></figure>
<p>Pronto! A partir de agora, todo o commit que enviar no git, será assinado com a chave que você definiu, de forma automática!</p>
<h2 id="_-enviando-um-commit-para-o-github">&gt;_ Enviando um Commit para o GitHub</h2>
<p>Vamos agora enviar um commit para o Github, para testar se tudo está funcionando corretamente. Pra isso, eu criei em meu repositório um novo arquivo, chamado <strong>teste-commit.txt</strong>, adicionei ele, executando o comando <em>git add</em>, e depois, executei o comando <em>git commit</em>. Por fim, fiz o <em>git push</em>.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">git add teste-commit.txt
git commit <span class="nt">-m</span> <span class="s2">"Adicionando arquivo teste-commit.txt"</span>
git push origin main</code></pre></figure>
<p>Quando fizer o <em>git commit</em>, será solicitado para colocar a palavra passe da chave GPG, para que possa ser assinado esse commit. Após realizar os comandos acima, temos este resultado:</p>
<p><img src="https://stephan-lopes.github.io/assets/images/assinatura-de-commits-com-gpg/1311245618908.png" alt="Imagem" /></p>
<p>Veja que com isso, temos um commit assinado! Podemos ver isso, com a badge de <strong>Verified</strong> nele. No caso de estar <strong>Unverified</strong>, semelhante com o que aparece abaixo, verifique seu commit, e veja se o nome de usuário, o email e a chave GPG estão corretos. Verifique também se colocou a chave GPG Pública corretamente no Github.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/assinatura-de-commits-com-gpg/2013428650008.png" alt="Imagem" /></p>
<h2 id="_-definindo-cache-de-chaves-gpg">&gt;_ Definindo Cache de Chaves GPG</h2>
<p>Embora tenhamos definido uma forma com que todos os commits sejam assinados, teremos que colocar a passphrase todas as vezes que fizermos um commit. Por mais que isso dê mais segurança, para algumas pessoas pode ser um problema, pois, a cada vez que fizermos um commit, o git irá pedir a passphrase.</p>
<p>Podemos então, definir um cache, fazendo com que o agent armazene temporariamente a passphrase. No tutorial, iremos definir esse período em 1 hora, mas, como você poderá ver, podemos definir qualquer período.</p>
<p>Para realizar essa tarefa, precisamos criar um arquivo chamado <strong>~/.gnupg/gpg-agent.conf</strong>. E dentro dele, definir o seguinte:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">default-cache-ttl 3600
max-cache-ttl 3600</code></pre></figure>
<p>Por fim, reinicie o agent, com o seguinte comando:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gpgconf <span class="nt">--kill</span> gpg-agent</code></pre></figure>
<p>Dessa forma, ele irá armazenar a passphrase, depois de digitada, por uma hora. Após o prazo, o agent irá pedir a passphrase novamente.</p>
<h2 id="_-assinando-commits-antigos">&gt;_ Assinando Commits Antigos</h2>
<p>Mostramos como faz para assinar os novos Commits, mas, e caso queira assinar commits antigos, como podemos fazer isso?</p>
<p>Uma forma que você pode fazer isso, é utilizando o comando <strong>git rebase</strong>. Com esse comando, ele irá assinar os commits não assinados. Lembre-se que o e-mail deve ser o mesmo da chave, sendo assim, em alguns casos, será necessário alterar o e-mail também.</p>
<p>Abaixo, vamos fazer um rebase, para que o git assine os commits antigos e altere o e-mail, de todos os commits. Entretanto, o código abaixo serve como um exemplo pro tutorial, e não algo a ser seguido, até porque ele modifica todas as datas, não mantendo as datas antigas.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">git rebase <span class="nt">--exec</span> <span class="s1">'git commit --amend --author="stephan-lopes &lt;40838038+stephan-lopes@users.noreply.github.com&gt;" --no-edit -S -n'</span> <span class="nt">--root</span></code></pre></figure>
<p>Com esse comando, ele irá modificar o autor do commit, e assinar ele. Talvez não seja a melhor forma de se fazer isso, para o seu caso. Estou apenas demonstrando que é possível fazer essa assinatura de commits anteriores.</p>
<h2 id="_-bloquear-pushes-que-exponham-o-e-mail-público">&gt;_ Bloquear Pushes que exponham o e-mail público</h2>
<p>Pode acontecer de você acabar em algum momento, definindo seu e-mail, e acabar esquecendo de mudar para o e-mail no-reply. Para evitar que faça um push e exponha ele, existe uma configuração no GitHub, que permite impedir isso.</p>
<p>No seu perfil, acesse <strong>Settings</strong>, posteriormente, acesse <strong>Emails</strong>, e por fim, marque a caixa onde está escrito <strong>Block command line pushes that expose my email</strong>.</p>
<p>Com isso, toda vez que você tentar enviar um push, expondo o seu endereço de e-mail público, será impedido.</p>
<h2 id="_-modo-vigilante">&gt;_ Modo Vigilante</h2>
<p>É possível adicionar o Modo Vigilante. Isso faz com que todos os seus commits, tanto os atuais, como os anteriores, mostrem se você é realmente você. Se o Commit não for assinado, ou está assinado, mas a assinatura é completamente diferente, o commit é definido como <strong>Unverified</strong>. Se o nome do Autor é diferente, mas o e-mail é igual, ele mostra <strong>Partially Verified</strong>. Se ele estiver com e-mail e usuário iguais o da assinatura, ele mostra <strong>Verified</strong>.</p>
<p>Para ativar o modo vigilante, no seu perfil, acesse <strong>Settings</strong>, posteriormente, acesse <strong>SSH and GPG Keys</strong>, e por fim, na seção de <strong>Vigilant Mode</strong> marque a caixa onde está escrito <strong>Flag unsigned commits as unverified</strong>.</p>
<h2 id="_-conclusão">&gt;_ Conclusão</h2>
<p>Neste tutorial/artigo, quis demonstrar um pouco mais sobre o problema de não assinar seus commits, mostrar como assinar commits, e como fazer um rebase para assinar commits antigos, caso opte por isso. Além disso, foi ensinado um pouco sobre geração de chave GPG, como configurar cache das chaves, e uma forma de não expor seu e-mail pessoal, mas sim um gerado pelo Github, para ter maior segurança em seus commits.</p>
<p>Também foi ensinado algumas formas de melhorar a identificação, utilizando o modo vigilante, e como impedir que seu endereço de e-mail seja exposto sem querer, em algum commit, quando usar o push. Espero que tenha gostado, e que esse artigo tenha sido útil. Caso você tenha ainda mais interesse em me ajudar, curta e compartilhe o artigo, além de interagir com sugestões, dúvidas, e comentários, na seção de comentários abaixo.</p>
<div class="breaker"></div></content><author><name>keven</name></author><category term="blog" /><category term="gpg" /><category term="git" /><category term="github" /><category term="guia-rapido" /><summary type="html">No Git, toda vez que é feito um commit, ele coleta seu usuário e seu e-mail, e anexa em um Commit. Entretanto, ele pode ser manipulado, e alguém pode se passar por você. Sendo assim, o ideal é assinar seus commits com chave GPG. Com ela, você consegue comprovar que você é você, para todos aqueles que possuem uma chave pública da chave privada que só você possuí. Este tutorial, é um guia de configuração, bem como a demonstração do problema em si, e em como resolvê-lo. Espero que gostem, e coloquem em prática as dicas!</summary></entry><entry><title type="html">Vagrant + Kaspersky: Download de Imagens Sem Perder a Segurança</title><link href="https://stephan-lopes.github.io/blog/vagrant-kaspersky-download-de-imagens-sem-perder-a-seguran%C3%A7a/" rel="alternate" type="text/html" title="Vagrant + Kaspersky: Download de Imagens Sem Perder a Segurança" /><published>2022-01-24T00:01:00+00:00</published><updated>2022-01-24T00:01:00+00:00</updated><id>https://stephan-lopes.github.io/blog/vagrant-kaspersky-download-de-imagens-sem-perder-a-seguran%C3%A7a</id><content type="html" xml:base="https://stephan-lopes.github.io/blog/vagrant-kaspersky-download-de-imagens-sem-perder-a-seguran%C3%A7a/"><p><em>O funcionamento do Kaspersky em conjunto de Máquinas Virtuais, ou imagens, criadas através do Vagrant, é um pouco dificultoso. Isso ocorre por uma funcionalidade do Kaspersky que protege sua rede. Neste artigo, explico como contornar esse problema, sem precisar desativar temporariamente o antivírus, ou então, desativar essa função, que tem como foco proteger o usuário.</em></p>
<h2 id="_-o-problema">&gt;_ O Problema</h2>
<p>O problema ocorre quando tenta conseguir a imagem que não pode ser encontrada localmente no dispositivo onde deseja iniciar o Vagrant. Por exemplo, após executar um vagrant init centos/7 e executar um vagrant up, um erro é mostrado para o usuário:</p>
<p><img src="https://stephan-lopes.github.io/assets/images/vagrant-kaspersky-download-de-imagens-sem-perder-a-segurança/1642996839628.png" alt="Imagem do Problema" /></p>
<p>Esse tipo de erro impede o Vagrant de efetuar o download da imagem, através do Vagrant Cloud, e posteriormente, do Centos.</p>
<h2 id="_-solução">&gt;_ Solução</h2>
<p>Para resolver o problema, precisamos entender como funciona essa funcionalidade do Antivírus.</p>
<h3 id="-entendendo-o-funcionamento">$ Entendendo o Funcionamento</h3>
<p>A Kaspersky Security bloqueia alguns sites de realizarem determinadas tarefas, verificando as conexões criptografadas. Isso é feito para garantir a segurança do usuário.</p>
<p>Isso não quer dizer que os sites tenham vulnerabilidade, ou não sejam seguros. Apenas é o motivo do porque a Kaspersky não permitir a conexão, da forma esperada, com esses servidores.</p>
<h3 id="-resolvendo-o-problema">$ Resolvendo o Problema</h3>
<p>Existem algumas formas de contornar o problema. Uma delas seria <strong>desativar o antivírus durante esse processo</strong>. Dentre todas as alternativas neste artigo, essa é a pior delas. O motivo é simples: Deixa o seu computador ou dispositivo inseguro por um período de tempo. Nesse espaço de tempo, em que ele está inativo, o seu dispositivo pode ser comprometido.</p>
<p>A segunda forma, seria <strong>desativar esse tipo de verificação de conexões criptografadas</strong>, o que seria uma outra forma que pode deixar seu dispositivo inseguro. Caso você acesse um site malicioso, poderá não ser impedido pelo antivírus. Ou se fizer uma conexão de criptografia que ele julgue, quando está ativo, como fraca ou insegura, sua comunicação pode estar correndo um risco de ser comprometida, e/ou interceptada.</p>
<p>A melhor forma, é apenas liberar para alguns domínios específicos, informando em uma lista, os endereços que devem ser ignorados nessa regra. Siga o passo abaixo:</p>
<p>Abra a tela do Kaspersky Security. Após isso, aperte no botão de engrenagem (configurações), e acesse a seção de gerenciamento de redes (Configurações de Rede). Após todos esses passos, busque entre as opões a seção de <strong>Verificação de Conexões Criptografadas</strong>, e busque por um botão de <strong>Endereços Confiáveis</strong>.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/vagrant-kaspersky-download-de-imagens-sem-perder-a-segurança/1643003270925.png" alt="Imagem" /></p>
<p>Adicione um novo endereço, informando posteriormente o nome de domínio do Vagrant Cloud (vagrantcloud.com), e deixe ele como ativo. Faça o mesmo procedimento com o domínio do Centos. Após concluir os passos, clique em Salvar.</p>
<h2 id="_-conclusão">&gt;_ Conclusão</h2>
<p>Quando testar novamente o comando vagrant up, observará que tudo dará certo, sem reclamar de certificado, e, comparado com as outras opções, realizando todo o processo de uma forma mais segura. Caso deseje mais segurança, após o download da imagem você pode desativar os endereços dentro da lista de endereços confiáveis, sem excluir eles. Isso permite que você ative essa regra apenas quando precisar.</p>
<div class="breaker"></div></content><author><name>keven</name></author><category term="blog" /><category term="vagrant" /><category term="windows" /><category term="kaspersky" /><category term="virtualbox" /><category term="security" /><category term="guia-rapido" /><summary type="html">O funcionamento do Kaspersky em conjunto de Máquinas Virtuais, ou imagens, criadas através do Vagrant, é um pouco dificultoso. Isso ocorre por uma funcionalidade do Kaspersky que protege sua rede. Neste artigo, explico como contornar esse problema, sem precisar desativar temporariamente o antivírus, ou então, desativar essa função, que tem como foco proteger o usuário.</summary></entry><entry><title type="html">Guia Rápido: WSL + Virtualbox</title><link href="https://stephan-lopes.github.io/blog/guia-rapido-wsl-virtualbox/" rel="alternate" type="text/html" title="Guia Rápido: WSL + Virtualbox" /><published>2021-11-09T00:01:00+00:00</published><updated>2021-11-09T00:01:00+00:00</updated><id>https://stephan-lopes.github.io/blog/guia-rapido-wsl-virtualbox</id><content type="html" xml:base="https://stephan-lopes.github.io/blog/guia-rapido-wsl-virtualbox/"><p><em>Recentemente o VirtualBox fez algumas atualizações, criando assim uma serie de problemas entre essas duas ferramentas (VirtualBox e WSL). Com isso, algumas pessoas foram obrigadas a escolher entre habilitar ou desabilitar o hipervisor, e escolher entre o WSL ou VirtualBox. Até a data dessa postagem, não há uma solução nas versões mais recentes, entretanto, é possível contorná-la.</em></p>
<h2 id="_-o-problema-com-o-virtualbox">&gt;_ O Problema com o VirtualBox</h2>
<p>O problema consiste em usar a versão mais atualizada do VirtualBox, em conjunto com o WSL (Subsistema do Linux no Windows). Quando tentava criar uma máquina com o VirtualBox, a seguinte mensagem aparecia na tela:</p>
<figure class="highlight"><pre><code class="language-raw" data-lang="raw">[...] NEMR0InitVMPart2 failed: VERR_NEM_INIT_FAILED (VERR_NEM_VM_CREATE_FAILED)</code></pre></figure>
<p>Com isso a máquina não é iniciada. A sugestão que é dada na maioria dos fóruns, seria a desabilitar o hipervisor, que está habilitado, usando o seguinte comando, em um powershell:</p>
<figure class="highlight"><pre><code class="language-powershell" data-lang="powershell"><span class="n">bcdedit</span><span class="w"> </span><span class="nx">/set</span><span class="w"> </span><span class="nx">hypervisorlaunchtype</span><span class="w"> </span><span class="nx">off</span></code></pre></figure>
<p>Isso resolve o problema com o Virtualbox, mas criamos outro problema, agora com o WSL.</p>
<h2 id="_-o-problema-com-o-wsl">&gt;_ O Problema com o WSL</h2>
<p>Após fazer o passo anterior, você deve reiniciar o computador. E quando ele inicia, você têm uma nova surpresa: seu WSL não funciona mais. E como faz para fazer funcionar novamente? Tem que habilitar o hipervisor. E nessa brincadeira, você fica tendo que escolher o que é mais importante, o WSL ou o Virtualbox, para seu ambiente de desenvolvimento.</p>
<p>Alguns outros fóruns irão recomendar em ativar recursos adicionais do Windows, que se você não sabe para que servem, sugiro não ativar, pois poderá causar outros problemas. Seria igual a se mexer tentando sair de uma areia movediça, você só se afunda mais. Em meus testes inclusive, nenhum deles funcionou com ambos ativos (WSL + Virtualbox).</p>
<p>Se fez o passo anterior e quer de volta o seu WSL, use o comando abaixo, e reinicie sua máquina:</p>
<figure class="highlight"><pre><code class="language-powershell" data-lang="powershell"><span class="n">bcdedit</span><span class="w"> </span><span class="nx">/set</span><span class="w"> </span><span class="nx">hypervisorlaunchtype</span><span class="w"> </span><span class="nx">auto</span></code></pre></figure>
<h2 id="_-a-solução-contornando-os-problemas-com-downgrade">&gt;_ A Solução: Contornando os Problemas com Downgrade</h2>
<p>A solução que encontrei para contornar este problema é fazer o downgrade do Virtualbox para uma versão anterior que não estivesse com este bug. Com isso, fiz o downgrade para a versão 6.1.26 (atualmente estamos na 6.1.28), e reiniciei a máquina host. Após isso, ambos os dois, WSL e Virtualbox, voltaram a funcionar. Você pode instalar a mesma versão que instalei através deste <a href="https://www.virtualbox.org/wiki/Download_Old_Builds_6_1">link</a>.</p>
<p>Ainda assim, é possível que encontre alguns problemas. Um deles pode ser derivado das suas antigas máquinas virtuais. Algumas delas podem não ser mais acessíveis. Se acontecer algum erro como esse, sugiro remover manualmente o diretório da máquina, que fica localizado por padrão em <span class="evidence">C:\&lt;nome_do_usuario&gt;\VirtualBox VMs\</span></p>
<div class="breaker"></div></content><author><name>keven</name></author><category term="blog" /><category term="wsl" /><category term="windows" /><category term="virtualbox" /><category term="guia-rapido" /><summary type="html">Recentemente o VirtualBox fez algumas atualizações, criando assim uma serie de problemas entre essas duas ferramentas (VirtualBox e WSL). Com isso, algumas pessoas foram obrigadas a escolher entre habilitar ou desabilitar o hipervisor, e escolher entre o WSL ou VirtualBox. Até a data dessa postagem, não há uma solução nas versões mais recentes, entretanto, é possível contorná-la.</summary></entry><entry><title type="html">Rsyslog #01: Configurando um Servidor de Log Básico</title><link href="https://stephan-lopes.github.io/blog/rsyslog-01-configurando-um-servidor-de-log-b%C3%A1sico/" rel="alternate" type="text/html" title="Rsyslog #01: Configurando um Servidor de Log Básico" /><published>2021-10-05T00:00:00+00:00</published><updated>2021-10-05T00:00:00+00:00</updated><id>https://stephan-lopes.github.io/blog/rsyslog-01-configurando-um-servidor-de-log-b%C3%A1sico</id><content type="html" xml:base="https://stephan-lopes.github.io/blog/rsyslog-01-configurando-um-servidor-de-log-b%C3%A1sico/"><p><em>As mensagens em uma rede de computadores podem ser centralizadas em um único servidor. Quando centralizadas, fica mais fácil o gerenciamento, análise e solução de problemas relacionados as máquinas presentes nesta rede. O artigo a seguir, tem como objetivo ensinar a como configurar um servidor de log básico utilizando essa ferramenta, e introduzir ao leitor conceitos de Facilidade e Nível.</em></p>
<h2 id="_-o-que-é-um-servidor-de-log">&gt;_ O que é um servidor de Log?</h2>
<p>Basicamente, um servidor de log, seria uma máquina que centraliza todas as mensagens de algumas máquinas em uma rede, para que sejam armazenadas, e posteriormente, com outras ferramentas, analisadas. A necessidade de um servidor centralizado de Log, é essencial, quando temos mais de um (diria 2 ou mais) servidores. Além de manter os dados em um outro servidor, garantindo assim uma certa dificuldade de alterá-los caso haja um incidente de segurança da informação, ele também permite a centralização dos logs de diversos servidores, que poderão ser analisados em um único local.</p>
<p>Imagine você tendo que cuidar de mais de 500 servidores… Ficaria difícil, em algumas situações, identificar algum problema, sem um servidor de log centralizado, não é mesmo?</p>
<h2 id="_-qual-servidor-de-log-devo-utilizar">&gt;_ Qual servidor de Log devo utilizar?</h2>
<p>Existem inúmeras alternativas no mercado, como por exemplo syslog-ng, rsyslog, logstash, e até mesmo, se formos pra nuvem, o CloudWatch da AWS, dentre outros. Neste artigo, meu foco será introduzi-lo ao Rsyslog. Entretanto, nada impede que você, leitor, utilize outra ferramenta. Apenas devo informar que, provavelmente, o artigo não servirá para a ferramenta escolhida, caso a ferramenta escolhida seja diferente.</p>
<h2 id="_-considerações">&gt;_ Considerações</h2>
<p>Como forma de melhorar o entendimento, estarei disponibilizando um arquivo Vagrantfile no fim do artigo que possibilitará a criação de um ambiente de estudo. Os requisitos para o artigo, no entanto, serão apenas duas máquinas, sendo uma que servirá de <strong>Cliente</strong> e outra como <strong>Servidor</strong>. Utilizarei Centos/7 em ambas as duas, por familiaridade. Caso tenha uma familiaridade com outra distribuição Linux, fique a vontade de utilizá-la. Não serão utilizadas máquinas Windows.</p>
<p>Com essas considerações, vamos a mão na massa!</p>
<h2 id="_-criando-o-ambiente-de-estudo">&gt;_ Criando o ambiente de estudo</h2>
<p>Caso tenha optado por utilizar o arquivo Vagrantfile, fornecido no artigo para criar seu ambiente de estudo, apenas execute o comando abaixo para criar o ambiente:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">vagrant up</code></pre></figure>
<p>O processo de criação demora um certo tempo, até que todas as máquinas sejam criadas. Após a criação, para acessar as máquinas, execute os comandos abaixo:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">vagrant ssh server <span class="c"># ---&gt; Entra na máquina do servidor</span>
vagrant ssh client <span class="c"># ---&gt; Entra na máquina do cliente</span></code></pre></figure>
<h2 id="_-instalando-o-rsyslog">&gt;_ Instalando o Rsyslog</h2>
<p>Por padrão, as máquinas Centos/7 já possuem o Rsyslog instalado. Entretanto, ele é de algumas versões anteriores do mesmo. Para ver a versão do Rsyslog na máquina <strong>Cliente</strong> e <strong>Servidor</strong>, utilize o comando abaixo:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">rsyslogd <span class="nt">-v</span></code></pre></figure>
<p><img src="https://stephan-lopes.github.io/assets/images/rsyslog-01-configurando-um-servidor-de-log-básico/1628350418210.png" alt="Imagem" /></p>
<p>A versão mais recente do Rsyslog, no momento que escrevo este artigo, é a 8.2106.0. Olhando no site do Rsyslog, notamos que a versão 8.24, é de outubro de 2017. Em um próximo artigo será introduzida a linguagem RainerScript, por isso é necessário que uma versão mais atualizada esteja presente, evitando assim, possíveis problemas de incompatibilidade com a linguagem.</p>
<p>Vamos então incluir o repositório oficial do Rsyslog, para conseguir um binário pré-compilado atualizado. Para isso, basta executar os seguintes comandos abaixo com o usuário <strong>root</strong> em ambas as máquinas (<strong>Servidor</strong> e <strong>Cliente</strong>):</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="nb">cd</span> /etc/yum.repos.d/
wget http://rpms.adiscon.com/v8-stable/rsyslog.repo
yum <span class="nb">install </span>rsyslog <span class="nt">-y</span></code></pre></figure>
<p>Após a execução dos comandos, teremos a versão mais atualizada do Rsyslog (versão estável)</p>
<p><img src="https://stephan-lopes.github.io/assets/images/rsyslog-01-configurando-um-servidor-de-log-básico/1628352331901.png" alt="Imagem" /></p>
<h2 id="_-subindo-servidor-rsyslog-legado">&gt;_ Subindo servidor Rsyslog (legado)</h2>
<p>Com a versão mais recente do programa instalada, podemos agora criar o nosso <strong>Servidor</strong>. É possível criar um <strong>Servidor</strong> rsyslog de forma muito simples, entretanto, legada. Ela utiliza a forma anterior ao qual o Rsyslog trabalhava seus arquivos de configuração. O arquivo de configuração padrão do Rsyslog, é o arquivo presente em <em>/etc/rsyslog.conf</em>.</p>
<p>No diretório <em>/etc/rsyslog.d/</em> ficam os arquivos que são importados pelo rsyslog. Nele que você pode configurar regras personalizadas. Uma boa prática, é criar seus <em>rulesets</em> personalizados neste diretório, ao invés de criar no arquivo <em>rsyslog.conf</em>.</p>
<p>Vamos configurar primeiramente nosso <strong>Servidor</strong>. Pra isso, iremos remover o comentário das seguintes linhas:</p>
<p><img src="https://stephan-lopes.github.io/assets/images/rsyslog-01-configurando-um-servidor-de-log-básico/1628385769857.png" alt="Imagem" /></p>
<p>Salve o arquivo, e execute o comando abaixo:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">systemctl restart rsyslogd</code></pre></figure>
<p>Isso fará com que o Servidor seja reiniciado, e com isso, carregue o arquivo de configuração novamente. Dessa forma, ele saberá que deve escutar na porta 514 - como define a linha onde está presente $UDPServerRun 514 - e que deve ser pelo protocolo UDP.</p>
<p>Certo. Mas será que ele está funcionando? Será que está recebendo log? Bom, precisamos sabermos isso. Primeiramente, vamos verificar se o <strong>Servidor</strong> está funcionando corretamente. Digite em seu terminal:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">systemctl status rsyslogd</code></pre></figure>
<p>Está com status ativo? Está rodando? Ótimo. Já sabemos que o Servidor está sendo executado. Agora precisamos verificar se a porta no protocolo UDP está realmente aberta, executando o comando abaixo:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">netstat <span class="nt">-lnup</span> | <span class="nb">grep </span>514</code></pre></figure>
<p>Apareceu algum resultado? Se apareceu um resultado, temos agora um <strong>Servidor</strong> de Logs configurado.</p>
<p>Mas, calma aí… Não temos a certeza ainda que está funcionando. Isso porque o <strong>Servidor</strong> ainda não está coletando arquivo de logs de outros lugares, apenas dele mesmo. Precisamos configurar agora a máquina <strong>Cliente</strong>, para enviar logs para o servidor.</p>
<p><em>PS:. Antes de deixarmos o <strong>Servidor</strong> de lado por um momento, e configurarmos a máquina <strong>Cliente</strong>, execute o comando abaixo, e anote o endereço IP da máquina <strong>Servidor</strong>:</em></p>
<p><img src="https://stephan-lopes.github.io/assets/images/rsyslog-01-configurando-um-servidor-de-log-básico/1628909014687.png" alt="Imagem" /></p>
<p><em>Mais tarde, enquanto estivermos configurando a máquina <strong>Cliente</strong>, precisaremos especificar para onde estaremos enviando os logs, e iremos informar que será para este endereço IP.</em></p>
<h2 id="_-configurando-cliente-rsyslog-legado">&gt;_ Configurando cliente Rsyslog (Legado)</h2>
<p>Com o <strong>Servidor</strong> já configurado, vamos então para a máquina <strong>Cliente</strong>. Acesse ela em outra aba do terminal, e abra o arquivo de configuração em <em>/etc/rsyslog</em>.conf. No fim do arquivo, adicione a seguinte linha de código:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="k">*</span>.<span class="k">*</span> @&lt;ENDEREÇO_IP&gt;</code></pre></figure>
<p>PS:. Substitua o <ENDEREÇO_IP>, pelo endereço IP do Servidor ao qual você anotou no passo anterior.</ENDEREÇO_IP></p>
<h2 id="_-testando-configuração-de-comunicação-cliente-servidor">&gt;_ Testando configuração de comunicação Cliente-Servidor</h2>
<p>Precisamos testar agora se o <strong>Cliente</strong> está enviando os logs para o <strong>Servidor</strong> centralizado. Salve o arquivo, e saia dele, caso ainda não tenha feito. O próximo passo é reiniciar o serviço rsyslog da máquina <strong>Cliente</strong>, utilizando o mesmo comando que usamos anteriormente para reiniciar o serviço na máquina <strong>Servidor</strong>:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">systemctl restart rsyslogd</code></pre></figure>
<p>Reiniciou? Vamos verificar se o serviço está funcionando, executando o comando abaixo:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">systemctl status rsyslogd</code></pre></figure>
<p>Está ativo? Se estiver, então a nova linha que adicionamos no arquivo de configuração do Rsyslog foi carregada pelo serviço. Os últimos passos, para verificar se o <strong>Servidor</strong> está funcionando seriam: executar um comando para ler um dos arquivo de log, neste caso, o <em>/var/log/messages</em>, e também, gerarmos um log de exemplo na máquina <strong>Cliente</strong>, para verificar se está sendo enviado para o <strong>Servidor</strong>.</p>
<p>Execute o comando abaixo no <strong>Servidor</strong>:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="nb">tail</span> <span class="nt">-f</span> <span class="nt">-n1</span> /etc/messages</code></pre></figure>
<p>Esse comando está mostrando de forma iterativa no terminal, toda novidade que for registrada no arquivo /etc/messages, dentro do <strong>Servidor</strong>.</p>
<p>Na máquina <strong>Cliente</strong>, execute o comando abaixo:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">logger <span class="nt">-p</span> info Mensagem de teste</code></pre></figure>
<p>Com esse comando, enviamos um log de teste para o serviço do Rsyslog, que irá salvar em algum dos arquivos ao qual nele foi dito para salvar. No nosso caso, ele irá enviar também para a máquina <strong>Servidor</strong>, como definimos adicionando aquela linha, no arquivo de configuração.</p>
<p>Volte agora para a máquina <strong>Servidor</strong> e verifique se chegou alguma mensagem, como a mensagem abaixo. Se chegou, então a máquina <strong>Servidor</strong> e a máquina <strong>Cliente</strong> estão conseguindo se comunicar corretamente.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/rsyslog-01-configurando-um-servidor-de-log-básico/1629071777012.png" alt="Imagem" /></p>
<h2 id="_-entendendo-configuração-da-máquina-cliente-e-servidor">&gt;_ Entendendo configuração da máquina Cliente e Servidor</h2>
<h3 id="servidor">Servidor</h3>
<p>Na máquina <strong>Servidor</strong>, descometamos a linha que permitia com que fosse possível o recebimento de arquivos de log via rede. Nós abrimos a porta 514 do protocolo UDP, para que a velocidade de entrega do log fosse maior. Entretanto, com isso, podemos perder alguns logs, já que não existe o <em>three handshake</em> presente no protocolo TCP. Aconselho utilizar o protocolo UDP apenas para quando você prioriza mais a velocidade de entrega, do que ter a garantia de recebimento da mensagem. Caso queira garantir a entrega da mensagem de log, use o TCP.</p>
<p>O TCP, apesar de garantir a entrega, acaba sendo mais lento. E no caso de queda do <strong>Servidor de logs</strong>, ele vai tentar garantir o envio da mensagem ao destino mesmo assim. Então ele vai ficar tentando enviar a mensagem, e tentando, e tentando… e tentando…</p>
<p>É possível também utilizar certificados TLS, junto com o protocolo TCP, o que permite com que sua mensagem não seja lida por terceiros, caso seja interceptada antes de chegar no <strong>Servidor</strong>. Entretanto, isso faz com que a velocidade acabe sendo mais prejudicada.</p>
<p>Uma alternativa para garantir a entrega da mensagem ao <strong>Servidor</strong>, uma velocidade maior que o módulo do <em>imtcp</em>, e também caso não necessite de um certificado TLS, é a utilização do módulo <em>imptcp</em>. Ele é mais simples que o módulo <em>imtcp</em>, mas não permite a criptografia por ele, tendo que ser realizada pelo software <em>stunnel</em> caso necessite. Neste último caso, em específico, utilize o <em>imtcp</em>.</p>
<h3 id="cliente">Cliente</h3>
<p>Na máquina <strong>Cliente</strong>, definimos qual seria o protocolo utilizado colocando apenas um “@” na frente do endereço IP do <strong>Servidor</strong> no arquivo de configuração. Isso definiu o protocolo de envio como UDP. Caso desejássemos utilizar o protocolo TCP, seriam dois “@” seguidos do endereço IP.</p>
<p>O <em>.</em>, definiu a facilidade e nível do log, em cada “*”, respectivamente. Isso diz que todos os logs de todos os níveis e facilidades são enviados ao <strong>Servidor de log</strong>. Poderíamos limitar que tipo de log seria enviado ao <strong>Servidor de log</strong>, através da facilidade, fazendo o seguinte, por exemplo:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">kern.<span class="k">*</span> @&lt;IP-DO-SERVIDOR&gt;</code></pre></figure>
<p>Agora, apenas os logs do kernel serão enviados para o <strong>Servidor</strong>.</p>
<p>Se quisermos, podemos também definir apenas um nível mais severo de log do kernel, para apenas logs de erros, ou mais críticos que isso, sejam enviados ao <strong>Servidor</strong>:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">kern.err @&lt;IP-DO-SERVIDOR&gt; </code></pre></figure>
<p>Agora, você receberá apenas logs de erro mais severos, como Error, Critical, Alert, e Emergency.</p>
<h2 id="_-conclusão">&gt;_ Conclusão</h2>
<p>Esse primeiro artigo sobre o Rsyslog, mostrou de uma forma simples, como criar um servidor de log centralizado. Entretanto, há muita coisa que podemos melhorar. Nos próximos artigos, irei me aprofundar mais no seu funcionamento, tipos de módulos existentes, entre outras análises, que em um artigo só, fica difícil escrever.</p>
<p>Gostou do artigo, tem alguma dúvida ou possui alguma sugestão para os próximos? Por favor, comente! Feedbacks me auxiliam a melhorar o conteúdo por aqui.</p>
<hr />
<h2 id="links">Links</h2>
<ul>
<li>Vagrantfile: <a href="https://gist.github.com/stephan-lopes/3213f88f44094ed8f25d5bfc328c9a5a">GitHub</a></li>
<li>Rsyslog Facilities and Levels: <a href="https://wiki.archlinux.org/title/rsyslog">GitHub</a></li>
</ul>
<div class="breaker"></div></content><author><name>keven</name></author><category term="blog" /><category term="rsyslog" /><category term="linux" /><category term="log" /><summary type="html">As mensagens em uma rede de computadores podem ser centralizadas em um único servidor. Quando centralizadas, fica mais fácil o gerenciamento, análise e solução de problemas relacionados as máquinas presentes nesta rede. O artigo a seguir, tem como objetivo ensinar a como configurar um servidor de log básico utilizando essa ferramenta, e introduzir ao leitor conceitos de Facilidade e Nível.</summary></entry><entry><title type="html">Camuflando Endereço IP em Testes de Segurança</title><link href="https://stephan-lopes.github.io/blog/camuflando-endere%C3%A7o-ip-em-testes-de-seguran%C3%A7a/" rel="alternate" type="text/html" title="Camuflando Endereço IP em Testes de Segurança" /><published>2020-05-18T00:01:00+00:00</published><updated>2020-05-18T00:01:00+00:00</updated><id>https://stephan-lopes.github.io/blog/camuflando-endere%C3%A7o-ip-em-testes-de-seguran%C3%A7a</id><content type="html" xml:base="https://stephan-lopes.github.io/blog/camuflando-endere%C3%A7o-ip-em-testes-de-seguran%C3%A7a/"><h2 id="introdução">Introdução</h2>
<p>Recentemente, estava procurando formas de camuflar o endereço IP, sem utilizar Whonix + Tor, ou Proxychains + Tor, que são dois métodos que podem ser utilizados para este objetivo. Estava vendo formas alternativas, devido a ambos os métodos, apesar de possuírem uma forma de camuflar o IP utilizando-se da rede Tor, acabam obrigando a fazer uma série de configurações (Whonix, por exemplo, precisa ser usado dentro de uma Maquina Virtual, e dependendo do uso, precisa ser configurado como Gateway), ou possuem algumas limitações (Proxychains, permite apenas abrir programas utilizando-se desse beneficio de utilizar o IP da rede Tor por padrão. E mesmo assim, ele acaba também limitando a funcionalidade de alguns programas).</p>
<p>Dessa forma, procurando, achei duas alternativas: uma não muito usual, utilizando VPNs do ProtonVPN, e outra mais fácil de se utilizar em testes de segurança, e também mais conhecida, utilizando a rede Tor para essa finalidade.</p>
<p>A seguir, estarei mostrando essas duas alternativas, assim como os testes realizados com ambas. Estarei disponibilizando no final do artigo, o endereço do repositório no GitHub, onde contêm o arquivo Vagrantfile, para caso queira realizar os testes em seu computador.</p>
<h2 id="protonvpn">ProtonVPN</h2>
<p>Uma das alternativa, é a utilização de uma VPN. Pode ser de qualquer provedor de VPN. Nesse artigo, me limito ao provedor ProtonVPN em sua versão gratuita, por conta da ferramenta que mostrarei logo em seguida. Lembrando que o artigo destina-se a testes de segurança autorizados (legalizados). Deixo bem claro isso, pois, utilizar esse método, gera rastro do seu IP real na VPN. Entretanto, a utilização da VPN, possibilita camuflar seu IP real em um ataque autorizado.</p>
<h3 id="configuração-e-utilização">Configuração e Utilização</h3>
<p>Para utilizar a alternativa acima, é necessário antes de tudo, que crie uma conta no site da ProtonVPN. Eles possuem alguns planos disponíveis, que vão de acordo com sua necessidade. Foi utilizada a versão gratuita para os testes.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589602859223.png" alt="Imagem" /></p>
<p>Após a criação e autenticação da conta, será necessário efetuar download do cliente para o sistema operacional em que deseja utilizá-lo. No caso desse artigo, foi utilizado o cliente para GNU/Linux, para distribuições Debian.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589648362557.png" alt="Imagem" /></p>
<p>Quando tiver terminado a instalação, é necessário efetuar configurações no cliente instalado. Para isso, digite no terminal:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="nb">sudo </span>protonvpn init</code></pre></figure>
<p>Com isso, você precisará entrar com as credenciais de acesso fornecidas na página de <strong>Conta</strong>, na seção de <strong>Nome de Usuário OpenVPN / IKEv2</strong>. Ele irá pedir para escolher um plano.</p>
<p>Como o cliente não me impediu de escolher, escolhi o plano Visionary, mesmo tendo o plano Free. Além disso, escolhi o protocolo UDP, entretanto, posteriormente durante os testes, mudei para TCP. Após isso, sua VPN já está configurada.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589649797942.png" alt="Imagem" /></p>
<p>Para conectar a VPN, basta digitar no terminal:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="nb">sudo </span>protonvpn connect</code></pre></figure>
<p>Então, serão dadas alguma opções, onde você poderá escolher a localidade, bem como, em qual servidor que deseja entrar.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589650323119.png" alt="Imagem" /></p>
<p>Fiz um teste, utilizando a ferramenta curl, onde verifiquei o meu endereço IP antes e depois de conectar na vpn. Criei um alias para ele em meu ~/.bashrc, chamado <strong>myip</strong>. Durante o artigo, quando ver esse comando digitado no terminal, saiba que ele apenas executa o comando abaixo:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">curl http://ipecho.net/plain<span class="p">;</span> <span class="nb">echo</span></code></pre></figure>
<p>A imagem abaixo, mostra que se conectou a VPN</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589651318732.png" alt="Imagem" /></p>
<h3 id="utilizando-em-testes-de-segurança-em-aplicações">Utilizando em Testes de Segurança em Aplicações</h3>
<p>Com tudo configurado, modifiquei alguns parâmetros para testar sua funcionalidade em uma simulação de um ambientes real. Durante o <em>protonvpn connect</em>, selecionei a opção de fazer a conexão via TCP ao invés de UDP. Não vou me atentar a explicar o motivo em detalhes, mas como foi simulado um ataque de tentativas de login em um servidor SSH, o método de conexão que precisava ser utilizado no ProtonVPN seria TCP.</p>
<p>Criei uma instância de VM no GCP, com uma imagem Ubuntu 16.04 LTS. Por padrão, a máquina já vem com algumas configurações do SSHGuard, que é quem vai escutar o arquivo de log, auth.log, e bloquear o endereço IP após algumas tentativas erradas de acesso. Como deixei a configuração por padrão, duas tentativas já são suficientes para bloquear o endereço IP no firewall.</p>
<p>O resultado do teste foi que, após duas tentativas erradas de acesso, ele bloqueou o endereço IP e na terceira tentativa, recebeu timeout. Isso aconteceu, por uma regra ter sido adicionada no Firewall pelo SSHGuard. Em outras palavras, ele não muda automaticamente o seu endereço IP, em casos de bloqueio pelo host, tendo que fazê-lo manualmente.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589656445456.png" alt="Imagem" /></p>
<p>Para mudar seu endereço IP manualmente, e randomicamente, sem ter que selecionar na lista, como feito anteriormente, basta executar o comando abaixo:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="nb">sudo </span>protonvpn connect <span class="nt">-r</span> <span class="nt">-p</span> tcp</code></pre></figure>
<p>Fazendo isso, você terá um novo endereço IP, ao qual poderá continuar com seus testes de segurança, sem ter que expor seu endereço de IP real.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589657377377.png" alt="Imagem" /></p>
<h3 id="gerando-novo-endereço-ip-a-cada-10-segundos">Gerando novo endereço IP a cada 10 segundos</h3>
<p>Talvez você se pergunte: “E se eu quiser automatizar essa mudança, e ficar, constantemente, mudando o endereço IP? Como eu poderia fazer isso?”. Existe uma ferramenta chamada IPChange. Ela faz isso de forma automatizada, utilizando ProtonVPN, tendo que apenas especificar o tempo que deseja que seja renovado o endereço IP. O repositório do GitHub para ela, encontra-se no final do artigo.</p>
<p>Não vou entrar em detalhes em como a ferramenta funciona, nem em seu uso. Estarei mostrando a seguir como fazer isso sem essa ferramenta, e deixando como um processo em segundo plano.</p>
<p>O comando abaixo, faz isso de forma automatizada, tendo apenas que mudar o tempo (em segundos) após o comando sleep. Isso se quiser alterar o tempo entre as mudanças de endereço IP:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="k">while</span> :<span class="p">;</span> <span class="k">do </span><span class="nb">sudo </span>protonvpn connect <span class="nt">-r</span> <span class="nt">-p</span> tcp<span class="p">;</span> <span class="nb">sleep </span>10<span class="p">;</span> <span class="k">done</span> &amp;&gt;/dev/null &amp; <span class="nb">alias </span><span class="nv">killchange</span><span class="o">=</span><span class="s2">"kill -9 </span><span class="nv">$!</span><span class="s2">"</span></code></pre></figure>
<p>Caso queira parar o processo, basta digital killchange:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">killchange</code></pre></figure>
<p>Porém, temos um problema. O processo de buscar um novo endereço de IP na ProtonVPN, acontece da seguinte forma: Você está utilizando o endereço IP “X” da VPN, e solicita para mudar de endereço IP. Então, o cliente do ProtonVPN desconecta você, fazendo-o voltar ao seu IP real. Logo em seguida, ele tenta se conectar a outra localidade. E quando conectado, lhe entrega para uso, o endereço IP “Y”.</p>
<p>Talvez se pergunte: “Qual o problema do que foi descrito acima?”. O problema consiste em que, você fica um período de tempo, mesmo que muito curto, com seu endereço IP real. Em um teste de segurança, por exemplo, isso pode acabar gerando logs com seu endereço IP real, fazendo o uso da ferramenta, desnecessário, caso não queira que isso aconteça. O tempo em que você volta para o seu IP real até se conectar novamente na VPN, consiste no seguinte cálculo:</p>
<blockquote>
<h4 id="tempo-com-endereço-ip-real--tempo-de-desconexão--tempo-de-conexão"><em>(Tempo com endereço IP real) = (Tempo de Desconexão) + (Tempo de Conexão).</em></h4>
</blockquote>
<p>Executei no terminal, um comando, para que continuamente, verificasse o endereço IP. Quando ele “travava”, eu sabia que era por conta de o comando myip ter sido executado na troca de IP. Por isso, eu acabei parando e executando-o novamente. Na imagem abaixo, mostro isso e, descrevo qual é o endereço IP da VPN e qual é o endereço IP real.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589662844516.png" alt="Imagem" /></p>
<p>Sendo assim, é necessária uma boa conexão, e se atentar para esse problema sabendo que ele pode acontecer. Colocar um tempo maior no comando <em>sleep</em>, e utilizar o endereço IP com menos frequência durante um ataque, são algumas alternativas que podem ajudar a contornar esse problema.</p>
<h2 id="anonsurf">AnonSurf</h2>
<p>A outra alternativa, seria o AnonSurf. Essa alternativa é popular, por conta de seu uso em distribuições como Kali Linux e Parrot OS. Você pode ver mais sobre o uso da ferramenta e suas outras formas de configuração, no repositório, que estará também no final do artigo.</p>
<h3 id="configuração-e-utilização-1">Configuração e Utilização</h3>
<p>Para configurar, é bem simples: basta clonar o repositório, entrar dentro do diretório e executar o script chamado installer.sh, que irá realizar todo o processo de instalação para você.</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">git clone https://github.com/Und3rf10w/kali-anonsurf <span class="o">&amp;&amp;</span> <span class="nb">cd </span>kali-anonsurf <span class="o">&amp;&amp;</span> <span class="nb">sudo</span> ./installer.sh</code></pre></figure>
<p>Pronto, o AnonSurf já está instalado! Caso deseja verificar se foi instalado corretamente, digite no terminal:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="nb">sudo </span>anonsurf</code></pre></figure>
<p>Caso apresente algumas informações, como na imagem abaixo, ele foi instalado corretamente.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589664813662.png" alt="Imagem" /></p>
<p>Para iniciar o serviço, digite:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="nb">sudo </span>anonsurf start</code></pre></figure>
<p>Após isso, acontecerá a conexão:</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589665078436.png" alt="Imagem" /></p>
<h3 id="utilizando-em-testes-de-segurança-em-aplicações-1">Utilizando em Testes de Segurança em Aplicações</h3>
<p>Após iniciado e em execução, realizei o mesmo teste que fiz com o ProtonVPN. Em outra máquina do GCP, fiz autenticações inválidas na porta 22 (SSH), na expectativa de que também fizesse o bloqueio do endereço IP. Entretanto, me surpreendi. Após algumas tentativas, notei que quando o endereço IP era bloqueado, o AnonSurf, de alguma forma, “reconhecia” esse fato, e alterava o endereço IP automaticamente.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589763982157.png" alt="Imagem" /></p>
<p>Dessa forma, não é necessário ficar alterando o endereço IP manualmente durante um ataque, mesmo sendo possível fazer isso. Como reduzi o escopo dos testes, em um ataque de autenticação de em um servidor SSH, é dificil dizer que terá o mesmo resultado em outros tipos de ataque.</p>
<p>Caso deseje mudar manualmente o endereço IP, basta digitar o seguinte comando:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="nb">sudo </span>anonsurf change</code></pre></figure>
<p>Dessa forma, você terá um novo endereço IP, ao qual poderá utilizar em seus testes.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589764477776.png" alt="Imagem" /></p>
<h3 id="gerando-novo-endereço-ip-a-cada-10-segundos-1">Gerando novo endereço IP a cada 10 segundos</h3>
<p>Diferente do ProtonVPN, desconheço de algum script, que faça isso para você, como o IPChange faz para o ProtonVPN. Entretanto, o mesmo código (com algumas alterações), utilizado no artigo para o ProtonVPN pode ser usado para o AnonSurf.</p>
<p>O comando abaixo funciona de forma semelhante de como funcionava com o ProtonVPN:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="k">while</span> :<span class="p">;</span> <span class="k">do </span><span class="nb">sudo </span>anonsurf change<span class="p">;</span> <span class="nb">sleep </span>10<span class="p">;</span> <span class="k">done</span> &amp;&gt;/dev/null &amp; <span class="nb">alias </span><span class="nv">killchange</span><span class="o">=</span><span class="s2">"kill -9 </span><span class="nv">$!</span><span class="s2">"</span></code></pre></figure>
<p>Caso queira parar o processo, basta digitar <em>killchange</em>:</p>
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">killchange</code></pre></figure>
<p>Em meus testes, verifiquei que mesmo com o serviço ligado, não acontecia a mudança tão demorada de IP, como acontece no ProtonVPN. O tempo da desconexão e de conexão é tão rápido, que não consegui notar se o tempo que ficava com o endereço IP real, era o suficiente pra gerar log, ou se então, nem sequer desconectava, mas sim, apenas mudava o endereço IP.</p>
<p><img src="https://stephan-lopes.github.io/assets/images/camuflando-endereço-ip-em-testes-de-segurança/1589765488796.png" alt="Imagem" /></p>
<p>Isso acaba auxiliando nos testes, em comparação com ProtonVPN, devido que, o mesmo acaba não gerando log com o endereço de IP real durante um ataque. Como a mudança de endereço IP é muito rápida, e não gerando log com seu endereço de IP real, é possível mudar o tempo colocando ele para um tempo abaixo dos 10 segundos.</p>
<p>Entretanto, uma coisa que notei durante os testes, foi que durante algumas tentativas de acesso ao servidor SSH o endereço IP que constava no arquivo de log no servidor, não condizia com o endereço IP que listava na minha máquina. Após o bloqueio do primeiro endereço IP pelo servidor, e a mudança automática do mesmo pelo AnonSurf, ele volta a condizer com o endereço IP da máquina nas próximas tentativas de autenticação.</p>
<p>Talvez não seja algo a se preocupar, mas fica uma pergunta no ar: “Se o endereço IP não condiz com o que está sendo utilizado na minha máquina, e eu sei que aquela tentativa de login que consta no log do servidor é minha, como pode essa tentativa chegar no servidor com outro endereço IP?”.</p>
<h2 id="conclusão">Conclusão</h2>
<p>Neste artigo, tive como finalidade mostrar essas duas ferramentas. Elas são alternativas ao Proxychains e Whonix, pra esconder o seu endereço IP real. Não quis me atentar em apenas descrever sobre elas, e dizer suas funcionalidades, mas sim em fazer uma análise dessas duas ferramentas, e em demonstrar tanto o lado positivo, como negativo de ambas, encontrados nos testes.</p>
<p>Ambas as ferramentas conseguem auxiliar um profissional de Segurança da Informação em testes de segurança. Elas conseguem esconder o endereço IP real, o que pode ajudar não ser idêntificado em diversos tipos de ataque. Entretanto, cabe ao profissional escolher qual delas cabe melhor ao uso em seus testes de segurança, podendo o mesmo utilizar de outras possibilidades não descritas no artigo.</p>
<p>Como limitei o escopo do artigo, muita coisa não foi falada sobre IPChange, sobre funcionalidades do ProtonVPN, e também outros usos do AnonSurf, como por exemplo iniciá-lo junto ao sistema.</p>
<hr />
<h2 id="repositórios">Repositórios</h2>
<ul>
<li>Vagrantfile: <a href="https://github.com/TheSubmitEquals/protonvpn-anonsurf-test">GitHub</a></li>
<li>AnonSurf: <a href="https://github.com/Und3rf10w/kali-anonsurf">GitHub</a></li>
<li>IPChange: <a href="https://github.com/tuhin1729/IPChange">GitHub</a></li>
</ul>
<div class="breaker"></div></content><author><name>keven</name></author><category term="blog" /><category term="anonsurf" /><category term="protonvpn" /><category term="security" /><summary type="html">Introdução</summary></entry><entry><title type="html">ElliotBot</title><link href="https://stephan-lopes.github.io/blog/elliotbot/" rel="alternate" type="text/html" title="ElliotBot" /><published>2019-03-25T02:07:00+00:00</published><updated>2019-03-25T02:07:00+00:00</updated><id>https://stephan-lopes.github.io/blog/elliotbot</id><content type="html" xml:base="https://stephan-lopes.github.io/blog/elliotbot/"><p>Este é um projeto destinado para o gerenciamento de mensagens e uso administrativo do grupo no Telegram, <a href="https://guiaanonima.com">Guia Anônima</a></p>
<p>Para ter acesso ao repositório do projeto, acesse o link do <a href="https://github.com/TheMrKeven/ElliotBot">GitHub</a>.</p>
<h2 id="requisitos">Requisitos</h2>
<p>Caso deseje utilizar este Telegram Bot, ou executá-lo, precisará dos seguintes pacotes, presentes no <strong>requeriments.txt</strong>:</p>
<ul>
<li><strong>certifi==2019.3.9</strong></li>
<li><strong>chardet==3.0.4</strong></li>
<li><strong>idna==2.8</strong></li>