summaryrefslogtreecommitdiff
path: root/rss.xml
blob: 7ff0899306c33405d7b1fb032c293309ae6bada2 (plain)
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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">

<channel>
<title>LandChad.net: Web Guides for Internet Landchads!</title>
<description>Tutorials on minimalist webpage creation and server maintenance.</description>
<language>en-us</language>
<link>https://landchad.net/rss.xml</link>
<atom:link href="https://landchad.net/rss.xml" rel="self" type="application/rss+xml" />
<image>
<title>LandChad.net Web Guides for Internet LandChads</title>
<url>https://landchad.net/pix/chad.gif</url>
<link>https://landchad.net/rss.xml</link>
</image>

<!-- LB -->

<item>
<title>Server-Side Scripting with CGI</title>
<guid>https://landchad.net/cgi.html</guid>
<link>https://landchad.net/cgi.html</link>
<pubDate>Sun, 25 Jul 2021 14:29:44 -0400</pubDate>
<description><![CDATA[
    <header><h1>Server-Side Scripting with CGI</h1></header>
    
    <main>
        <p>
        The basic website tutorial here describes how to set up a static
        website &mdash; one that just serves HTML files saved on your server,
        and until you change something manually, the same content will be served
        each time a given page is requested. This is perfectly enough for most
        personal website needs. This is how blogs should be implemented, instead
        of relying on bloatware like WordPress!
        </p>
        <p>
        But sometimes you genuinely <i>do</i> need something more. You need your
        website to serve different contents depending on the time, on who the
        requester is, on the contents of a database, or maybe process user input
        from a form.
        </p>
        <h2>CGI</h2>
        <p>
        CGI, or the Common Gateway Interface, is a specification to allow you,
        the server owner, to program your web server using pretty much any
        programming language you might know. The specification is almost as old
        as the Internet itself and for a long time CGI scripting was the primary
        method of creating dynamic websites.
        </p>
        <p>
        CGI is a very simple specification indeed. You write a script in your
        favorite language, the script receives input about the request in
        environment variables, and whatever you print to the standard output
        will be the response. Most likely, though, you will want to use a
        library for your language of choice that makes a lot of this
        request/response handling simpler (e.g. parsing query parameters for
        you, setting appropriate headers, etc.).
        </p>
        <h3>Limitations of CGI</h3>
        <p>
        While in theory you could implement any sort of functionality with CGI
        scripts, it's going to get difficult managing a lot of separate scripts
        if they're supposed to be working in tandem to implement a dynamic
        website. If you want to build a full out web application, you'd probably
        be better off learning a web framework than gluing together Perl
        scripts.
        </p>
        <p>
        That said, just as most of the web could be replaced with static
        websites, much of the remaining non-static web could be replaced with a
        few simple scripts, rather than bloated Ruby on Rails or Django
        applications.
        </p>
        <h2>Let's write a CGI script!</h2>
        <p>
        We'll implement a simple example CGI script. I'll use Ruby for this
        tutorial, but you'll be able to follow along even if you don't know
        Ruby, just treat it as pseudocode then find a CGI library for your
        language.
        </p>
        <h3>The working example</h3>
        <p>
        Our working example will be the Lazy Calculator. Yeah, you're probably
        tired of seeing calculator examples in every programming tutorial, but
        have you ever implemented one that takes the weekends off?
        </p>
        <p>
        Here's how it will work. When in a browser you submit a request to your
        website like
        </p>
        <pre><code>example.com/calculator.html?a=10&amp;b=32</code></pre>
        <p>
        you will receive a page with the result of the addition of 10 and 32:
        42.
        </p>
        <p>
        <i>Unless</i> you send your request on a weekend. Then the website will
        respond with
        </p>
        <pre><code>I don't get paid to work on weekends! Come back Monday.</code></pre>
        <p>
        This example will show a few things that CGI scripts can do that you
        wouldn't have been able to get using just file hosting in your
        web server:
        <ul>
          <li> getting inputs from the user; </li>
          <li>
            getting external information (here just the system time, but you
            could imagine instead connecting to a database);
          </li>
          <li> using the above to create dynamic output. </li>
        </ul>
        <h3>The code</h3>
        <p>
        Here's an implementation of the lazy calculator as a Ruby CGI script:
        </p>
        <pre><code>#!/bin/env ruby
require 'cgi'
require 'date'
cgi = CGI.new
today = Date::today
a = cgi["a"].to_i
b = cgi["b"].to_i
if today.saturday? || today.sunday?
  cgi.out do
    "I don't get paid to work on weekends! Come back Monday."
  end
else
  cgi.out do
    (a + b).to_s
  end
end</code></pre>
        <p>
        Let's go through what's happening here.
        </p>
        <h3>The shebang line</h3>
        <p>
        CGI works by pointing your web server to an executable program. A Ruby
        or Python script by itself is not immediately executable by a computer.
        But on Unix-like systems you can specify the program that will be able
        to execute your file in its first line if it starts with <code>#!</code>
        (known as the shebang; read more about it on
        <a href="https://en.wikipedia.org/wiki/Shebang_(Unix)">Wikipedia</a>).
        </p>
        <p>
        So if you're going to be using a scripting language, you'll probably
        need the appropriate shebang line at the top of your script. If you use
        a compiled language, you'll just point your web server to the compiled
        executable binary.
        </p>
        <h3>Query parameters</h3>
        <p>
        The next interesting lines of code are where we set the variables
        <code>a</code> and <code>b</code>. Here we are getting user inputs from
        the request.
        </p>
        <p>
        In the example request we mentioned above
        (<code>example.com/calculator.html?a=10&amp;b=32</code>), the part
        starting from the question mark, <code>?a=10&amp;b=32</code>, is the
        <i>query string</i>. This is how users can submit parameters with their
        web requests. Usually these parameters are set by e.g. a form on your
        website, but in our simple example we'll be just manually manipulating
        the URL.
        </p>
        <p>
        The query string contains key-value pairs. The Ruby CGI library makes
        them available in the <code>CGI</code> object it provides. We just need
        to index it with the desired key, and we'll get the corresponding value.
        </p>
        <h3>Wrapping it up</h3>
        <p>
        The remaining parts of the code should be pretty self-explanatory. We
        get today's date, check if it's a Saturday or a Sunday, and depending on
        that, we instruct the CGI library to output either the answer, or a
        "come back later" message. 
        </p>
        <p>
        The Ruby library by default returns an HTML response, so we really
        should have wrapped our outputs in some <code>html</code>,
        <code>body</code>, etc. tags. Alternatively, we could have specified
        that the response is just plain text with
        </p>
        <pre><code>cgi.out 'text/plain' do</code></pre>
        <p>
        In general, your CGI library will probably have ways of specifying all
        sorts of HTTP response headers, like status code, content type, etc.
        </p>
        <h2>Making it work</h2>
        <p>
        We have a CGI script, now let's point our web server to it.
        </p>
        <h3>Installing FastCGI</h3>
        <p>
        If you're using Nginx, install <code>fcgiwrap</code>:
        </p>
        <pre><code>apt install fcgiwrap</code></pre>
        <p>
        This installs the necessary packages for Nginx to use FastCGI &mdash; a
        layer between your web server and CGI script that allows for faster
        handling of scripts than if the web server had to handle it all by
        itself.
        </p>
        <p>
        Other web servers will probably have a similarly simple way of enabling
        FastCGI, or you can look into other methods for launching CGI scripts.
        </p>
        <h3>Nginx configuration</h3>
        <p>
        In the configuration file for your website, add something like the
        following:
        </p>
<pre><code>location /calculator.html {
  include fastcgi_params;
  fastcgi_param SCRIPT_FILENAME /usr/local/bin/lazy-calculator.rb;
  fastcgi_param QUERY_STRING $query_string;
  fastcgi_pass unix:/run/fcgiwrap.socket;	
}</code></pre>
        <p>
        <code>fastcgi_param</code> directives specify various parameters for
        FastCGI. <code>SCRIPT_FILENAME</code> should point to your executable.
        For <code>QUERY_STRING</code>, we just copy Nginx's
        <code>$query_string</code> variable. You might want to pass other
        information to your CGI script as well, see for example
        <a href="https://wiki.debian.org/nginx/FastCGI">the Debian wiki</a> for
        a more detailed example, including pointing to an entire directory of
        CGI scripts, rather than adding each one by hand to your web server
        config.
        </p>
        <h2>Contribution</h2>
        <ul>
            <li>Martin Chrzanowski -- <a href="https://m-chrzan.xyz">website</a>, <a href="https://m-chrzan.xyz/donate.html">donate</a></li>
        </ul>
    </main>
	
]]></description>
</item>


<item>
<title>XMPP Server (Prosody)</title>
<guid>https://landchad.net/xmpp.html</guid>
<link>https://landchad.net/xmpp.html</link>
<pubDate>Wed, 21 Jul 2021 22:58:21 -0400</pubDate>
<description><![CDATA[
    <header><h1>XMPP Server (Prosody)</h1></header>

    <main>
        <img class=titleimg src="pix/xmpp.svg" alt="XMPP Logo and Icon">
        <p>XMPP is a fantastically simple protocol that's usually used as a messenger.
        It's highly extensible,
        better than IRC,
        lighter and more decentralized and Matrix
        and Telegram and normie social media can't hold a candle to it.
        </p>
        <p>
        XMPP is so decentralized and extensible that there are many <em>different</em> XMPP servers.
        Here, let's set up an <a href="https://prosody.im/">Prosody</a> XMPP server.
        </p>
        <h2>Installation</h2>
        <p>
        Prosody is in the Debian repositories, so we can easily install it on our server with the following command:
        </p>
        <pre><code>apt install prosody</code></pre>
<h2>Configuration</h2>
<p>
The Prosody configuration file is in <code>/etc/prosody/prosody.cfg.lua</code>.
To set it all up, we will be changing several things.
</p>
<h3>Setting Admins</h3>
<p>
Let's go ahead and set who our admin(s) will be.
Find the line that says <code>admins = { }</code> and to this we can specify one or more server admins.
</p>
<pre><code># To add one admin:
admins = { "chad@example.org" }
# We can add more than one by separating them by commas. (This file is written in Lua.)
admins = { "chad@example.org", "chadmin@example.org" }</code></pre>
<p>
Note that we have not created these accounts yet, we will do this <a href=#user>below</a>.
</p>
<h3>Set the Server URL</h3>
<p>
Find the line <code>VirtualHost "localhost"</code> and replace <code>localhost</code> with your domain.
In our case, we will have <code>VirtualHost "example.org"</code>
</p>
<h3>Multi-User Chats</h3>
<p>
Most people will probably want the ability to have chats with more than two users.
This is easily enough to enable.
In the config file, add the following:
</p>
<pre><code>Component "<strong>chat.example.org</strong>" "muc"
    modules_enabled = { "muc_mam" }
    restrict_room_creation = "admin"</code></pre>
<p>
On the first line, you must have a separate subdomain for your multi-user chats.
I use the <code>chat.</code> subdomain, but some use <code>muc.</code>.
Anything if possible.
</p>
<p>
The second line is important because it prevents non-admins from creating and squatting rooms on your server.
The only situation where you might not want that is if you indend to open a general public chat system for people you don't know.
</p>
<aside>
<p>
Read more about the <code>muc</code> plugin on the Prosody documentation page <a href="https://prosody.im/doc/modules/mod_muc">here</a>.
</p>
</aside>
<h3>End-to-end Encryption</h3>
<p>
Importantly, we'll want end-to-end encryption enabled for user privacy.
</p>
<p>
Find the array beginning with <code>modules_enabled</code>.
This includes a list of modules to be used.
Add
<code>"omemo_all_access";</code> to that list.
Additionally, be sure to change the module <code>pep</code> to <code>pep_simple</code> or this will cause a conflict.</p>
<p>
This module is not installed by default,
but you can easily download it by running the following command on the command prompt
to download and install the module to the correct directory.
</p>
<pre class=wide><code>curl -sL https://hg.prosody.im/prosody-modules/raw-file/785389a2d2b3/mod_omemo_all_access/mod_omemo_all_access.lua &gt; /usr/lib/prosody/modules/mod_omemo_all_access.lua</code></pre>
<h3>Other things to check</h3>
<p>Check the config file for other settings you might want to change.
For example, if you want to run a general public XMPP server, you can allow anyone to create an account by changing <code>allow_registration</code> to <code>true</code>.
</p>
<h2>Certificates</h2>
<p>
Obviously, we want to have client-to-server and server-to-server encryption.
Nowadays, use can use Certbot to generate certificates and use a convenient command below <code>prosodyctl</code> to import them.
</p>
<p>
<strong>If you have multi-user chat enabled, be sure to get a certificate for that subdomain as well.</strong>
Include the <code>--nginx</code> option assuming you have an Nginx server running.
</p>
<pre><code>certbot -d <strong>chat.example.org</strong> --nginx</code></pre>
<p>
Once you have the certificates for encryption, run the following to import them into Prosody.
</p>
<pre><code>prosodyctl --root cert import /etc/letsencrypt/live/</code></pre>
<p>
Note that you might get an error that a certificate has not been found if your <code>muc</code> subdomain and your main domain share a certificate.
It should still work, this is just notifying you that no specific
</p>
<p>
For user privacy, we will definitely want to install and enable encryption with OMEMO.
</p>
<h2 id=user>Creating users/admins manually</h2>
<p>
Let's manually create the admin user we prepared for above.
Note that you can indeed do this in your XMPP client if you have not disabled registration, but this is how it is done on the command line:
</p>
<pre><code>prosodyctl adduser <strong>chad@example.org</strong></code></pre>
<p>This will prompt you to create a password as well.</p>
<h2>Make changes active</h2>
<p>
With any system service, use <code>systemctl reload</code> or <code>systemctl restart</code> to make the new settings active:
</p>
<pre><code>systemctl restart prosody</code></pre>
<h2>Using your Server!</h2>
<p>
Once your server is set up, you just need an XMPP client to use your new and secure chat system.
</p>
<ul>
    <li>GNU/Linux: <a href="https://dino.im/">Dino</a> or <a href="https://gajim.org/">Gajim</a></li>
    <li>Windows: <a href="https://gajim.org/">Gajim</a> also runs on Windows.</li>
    <li>Android: <a href="https://conversations.im/">Conversations.im</a></li>
    <li>Mac/iOS: <a href="https://monal.im/">Monal IM</a> or <a href="https://siskin.im/">Siskin</a> for iOS alone</li>
    <li>command-line (GNU/Linux, MacOS, Windows): <a href="https://profanity-im.github.io/">Profanity</a></li>
    <li><a href="https://xmpp.org/software/clients.html">See a more complete list kept by XMPP</a></li>
</ul>
<p>
Install whichever of these clients you want on your computer or phone and you can log into your new XMPP server with the account you made.
Note that if you enabled public registration, anyone can create an account on your server through one of these clients.
</p>
<h3>Account addresses</h3>
<p>
XMPP account addressed look just like email addresses: <code><strong>username@example.org</strong></code>.
You can message any account on any XMPP server on the internet with that format.
</p>
<h3>Note on MUCs (multi-user chats)</h3>
<p>
Remember that MUCs are kept on a separate subdomain that we created and should've gotten a certificate for above, for example, <code><strong>muc.example.org</strong></code>.
Chatrooms are created and referred to in the following format: <code><strong>#chatroomname@muc.example.org</strong></code>.
</p>
    </main>

]]></description>
</item>


<item>
<title>Setting up RSS Bridge</title>
<guid>https://landchad.net/rss-bridge.html</guid>
<link>https://landchad.net/rss-bridge.html</link>
<pubDate>Mon, 05 Jul 2021 18:11:15 -0400</pubDate>
<description><![CDATA[
    <header><h1>Setting up RSS Bridge</h1></header>

    <main>
        <p>RSS Bridge is a useful utility you can use to help you avoid the big tech sites, like Facebook and Twitter, which instead of the feed you usually would see, will be a based and minimalist RSS feed. </p>
        <p>You'll need a server or VPS. Nearly any Operating system is supported but for this tutorial I'm gonna presume you're using a Debian-based OS. You'll also need a domain name pointing to your server's IP address <a href="https://landchad.net/dns.html">which is explained in this tutorial.</a>
        </p>
<h2>Installation</h2>
<h3>Setting Up and Configuring</h3>
<p>First things first you'll need to make sure that you've hardened you SSH so that password authentication is disabled and you'll also want to setup Fail2Ban.
There's a great tutorial on how to do this <a href="https://landchad.net/sshkeys.html">which can be read here.</a>
</p>
<p>
Next we'll install the required packages:
</p>
<pre><code>apt install -y curl unzip nginx certbot php-fpm php-mysql php-cli php7.3-mbstring php7.3-curl php7.3-xml php7.3-sqlite3 php7.3-json</code></pre>
<p>We now have to create the website configuration file. Create/open the a file below:</p>
<pre><code>nano /etc/nginx/sites-available/rss-bridge</code></pre>
<p>And add the following content:</p>
<pre><code>server {
    root /var/www/rss-bridge;
    index index.php index.html index.htm index.nginx-debian.html;
    server_name rss-bridge.<strong>example.org</strong>;
    location / {
            try_files $uri $uri/ =404;
    }
    location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
    }
    location ~ /\.ht {
            deny all;
    }
}
</code></pre>
<p>After you have saved the file, you need to create a symlink so the server actually will read the file.</p>
<pre><code>ln -s /etc/nginx/sites-available/rss-bridge /etc/nginx/sites-enabled/rss-bridge</code></pre>
<p>Then we have to create the folder where the service will reside in.</p>
<pre><code>mkdir -p /var/www/rss-bridge
cd /var/www/rss-bridge
</code></pre>
<p>Lets download the latest version of RSS-Bridge in the directory.</p>
<p>The newest version can be found <a href="https://github.com/RSS-Bridge/rss-bridge/releases">here</a>, at the time of writing that is "RSS-Bridge 2021-04-25."</p>
    <pre><code>wget https://github.com/RSS-Bridge/rss-bridge/archive/refs/tags/<strong>2021-04-25.zip</strong></code></pre>
<p>Unzip the file:</p>
<pre><code>unzip <strong>2021-04-25.zip</strong></code></pre>
<p>This will create a directory called rss-bridge-version-number, we now want to move all the file contents of the newly created directory to the one we are in</p>
<pre><code>mv <strong>rss-bridge-2021-04-25</strong>/* .
rm -rf <strong>rss-bridge-2021-04-25 2021-04-25.zip</strong>
</code></pre>
<p>Now all we need to do is grant read/write permissions and reload the web server.</p>
<pre><code>chown -R www-data:www-data /var/www/rss-bridge
systemctl reload nginx
</code></pre>
<p>That's it, you should now have a working rss-bridge installed. But you should definately get an SSL certifcate installed <a href="https://landchad.net/certbot.html">which is done briefly here</a>.</p>
<ul>
    <li><a href="https://handskemager.xyz">handskemager.xyz</a></li>
    <li>Bitcoin: <code class=crypto>bc1qhfjgwjzksf2auqjefwpvq20wvyugq3lhqgkxvu</code></li>
    <li>Monero: <code class=crypto>88cPx6Gzv5RWRRJLstUt6hACF1BRKPp1RMka1ukyu2iuHT7iqzkNfMogYq3YdDAC8AAYRqmqQMkCgBXiwdD5Dvqw3LsPGLU</code></li>
</ul>
    </main>

]]></description>
</item>


<item>
<title>Rsync: Upload and Sync Files and Websites</title>
<guid>https://landchad.net/rsync.html</guid>
<link>https://landchad.net/rsync.html</link>
<pubDate>Sat, 03 Jul 2021 08:58:29 -0400</pubDate>
<description><![CDATA[
<header><h1>Rsync: Upload and Sync Files and Websites</h1></header>
<main>
    <p>rsync is a simple way to copy files and folders between your local computer and server.</p>
    <p>It not only makes file-transfer easy, but it allows you to build and maintain your website offline, then easily upload it to the proper directory on your server so you don't need to constantly be logged into your server to modify your site.</p>
<h2 id="installing-rsync">Installing rsync</h2>
<p>Run the following on your server <em>and</em> on your local machine.</p>
<pre><code>apt install rsync</code></pre>
<h2 id="uploading-files-with-rsync">Uploading files with rsync</h2>
<p>From your local machine you can upload files to your server like this:</p>
<pre><code>rsync -ruvzP <strong>/path/to/file</strong> <strong>root@example.org:/path/on/the/server</strong></code></pre>
<p>You will be prompted for the root password and then uploading will commence.</p>
<p>If you omit <strong>root@</strong>, rsync will not attempt to log in as root, but whatever your local username is.</p>
<h3>Options to rsync</h3>
<p>In this command, we give several options to rsync:</p>
<ul>
    <li><code>-r</code> &ndash; run recurssively (include directories)</li>
    <li><code>-u</code> &ndash; update files (do not reupload files that are not changed since last upload)</li>
    <li><code>-v</code> &ndash; visual, show files uploaded</li>
    <li><code>-z</code> &ndash; compress files for upload</li>
    <li><code>-P</code> &ndash; if uploading a large file and upload breaks, pick up where we left off rather than reuploading the entire file</li>
</ul>
<p>Avoid using the commonly used <code>-a</code> option when uploading. It changes can transfer your local machine's user and group permissions to your server, which might cause breakage.</p>
<h3>Scriptability</h3>
<p>It's a good idea to build your website offline, then make an rsync script or bash alias like the one above to upload the edited files when you have made updates.</p>
<h3>Password-less authentication</h3>
<p>To avoid having to manually input your password each upload, you can set up <a href="sshkeys.html">SSH keys</a> to securely idenitify yourself and computer as a trusted.</p>
<h3>Picky trailing slashes</h3>
<p>rsync is very particular about trailing slashes. This is useful, but can be confusing to some new users. Suppose we run the following wanting to mirror our offline copy of our website in the directory we use on our server (<code>/var/www/websitefiles/</code>):</p>
<pre><code>rsync -ruvzP ~/<strong>websitefiles/</strong> root@example.org:/var/www/<strong>websitefiles/</strong></code></pre>
<p>This will <em>not actually do quite what we want</em>. It will take our local <code>websitefiles</code> directory and put it <em>inside</em> <code>websitefiles</code> on the remote machine, ending up with: <code>/var/www/websitefiles/websitefiles</code>.</p>
<p>Instead, remove the trailing slash from the remote server location:</p>
<pre><code>rsync -ruvzP ~/<strong>websitefiles/</strong> root@example.org:/var/www/<strong>websitefiles</strong></code></pre>
<p><code>websitefiles/</code> has been replaced with <code>websitefiles</code>, and this will do what we want.</p>
<h2 id="downloading-file-with-rsync">Downloading files with rsync</h2>
<p>You may just as easily download files and directories from your server with rsync:</p>
<pre><code>rsync -urvzP <strong>root@example.org:/path/to/file</strong> <strong>/path/to/file</strong></code></pre>
<h2 id="contribution">Contribution</h2>
<ul><li>el3ctr0lyte: <a href="https://github.com/el3ctr0lyte">github</a>, XMR: <code class=crypto>86DBJdiG83ZDea6kJgsbVN5tMae5ScfuhJ3PihEMTHatCrGEw2gctyUB92V2fz4R4YhwRaQeAGL5M4gPRXvVvtkULJi4ayk</code></li><li>Substantial revisions by <a href="https://lukesmith.xyz">Luke</a></li></ul>
</main>
]]></description>
</item>


<item>
<title>Setup a Pleroma Server</title>
<guid>https://landchad.net/pleroma.html</guid>
<link>https://landchad.net/pleroma.html</link>
<pubDate>Fri, 02 Jul 2021 09:14:32 -0400</pubDate>
<description><![CDATA[
    <header><h1>Setup a Pleroma Server</h1></header>

    <main>
        <p>Hopefully by now you won't have to be sold on the invasive practices that social media companies conduct. Websites such as Facebook and Twitter aquire so much data on users that they often know more about you than you know about yourself.
The simple solution to this is to not use social media. However, that just isn't an option for most people. So the next best thing is to setup a self-hosted and federalised social media site so that you have full control over your data.
I've previously made<a href="https://www.youtube.com/watch?v=l7mVsLSsotU"> a video showing all the steps in depth if you want to check it out.</a> If you run into any issues I suggest you look at the video.
</p>
        <p>You'll need a server or VPS. Nearly any Operating system is supported but for this tutorial I'm gonna presume you're using a Debian-based OS. You'll also need a domain name pointing to your server's IP address <a href="https://landchad.net/dns.html">which is explained in this tutorial.</a>
        </p>
<h2>Installation</h2>
<h3>Setting Up and Configuring</h3>
<p>First things first you'll need to make sure that you've hardened you SSH so that password authentication is disabled and you'll also want to setup Fail2Ban.
There's a great tutorial on how to do this <a href="https://landchad.net/sshkeys.html">which can be read here.</a>
</p>
<p>
Next we'll install the required packages:
</p>
<pre><code>apt install -y curl unzip libncurses5 postgresql postgresql-contrib nginx certbot libmagic-dev</code></pre>
<p>
You can manually configure postgreSQL to suit your system better. <a href="https://docs-develop.pleroma.social/backend/configuration/postgresql/">Check out the documentation here</a> and then run the below command:
</p>
<pre><code>systemctl restart postgresql</code></pre>
<h3>Installing the Pleroma App</h3>
<h4>First as the root user</h4>
<p>
Pleroma is not in the Debian app repositories, so we will install it manually.
First create the Pleroma user by running the below command:
</p>
<pre><code>useradd -m -s /bin/bash -d /opt/pleroma pleroma</code></pre>
<p>
Then, still as root, we will create the required directories and give the Pleroma user ownership of them.
</p>
<pre><code>mkdir -p /var/lib/pleroma/uploads
chown -R pleroma /var/lib/pleroma
mkdir -p /var/lib/pleroma/static
chown -R pleroma /var/lib/pleroma
mkdir -p /etc/pleroma
chown -R pleroma /etc/pleroma</code></pre>
<h4>Now, as the new Pleroma user</h4>
<p>
Now run <code>su -l pleroma</code> to login as the Pleroma user.
Now use the <code>curl</code> command below to download the Pleroma software and unzip it.
</p>
<pre><code>curl 'https://git.pleroma.social/api/v4/projects/2/jobs/artifacts/stable/download?job=<strong>amd64</strong>' -o /tmp/pleroma.zip
unzip /tmp/pleroma.zip -d /tmp/</code></pre>
<aside><p>Note that we are downloading the <strong>amd64</strong> version here. If you know you have a different CPU architecture, replace that with whatever your architecture is.</p></aside>
<pre><code>mv /tmp/release/* /opt/pleroma
rmdir /tmp/release
rm /tmp/pleroma.zip
./bin/pleroma_ctl instance gen --output /etc/pleroma/config.exs --output-psql /tmp/setup_db.psql</code></pre>
<p>We need to briefly return to the root user so we can run the following command (via the postgres user) to set up the database.
Type <code>ctrl-d</code> or run <code>exit</code> to return to the root user, then run:
</p>
<pre><code>su postgres -s $SHELL -lc "psql -f /tmp/setup_db.psql"</code></pre>
<p>Then return to the pleroma user with <code>su -l pleroma</code> and we will test to see that Pleroma can run:</p>
<pre><code>./bin/pleroma_ctl migrate
./bin/pleroma daemon</code></pre>
<p>
That will initialize Pleroma. It might take as long as a minute to get started, so wait a bit, then run the following:
</p>
<pre><code>curl http://localhost:4000/api/v1/instance</code></pre>
<p>If everything is working, this command will give you a long line of messy output. If it is not, you will get a connection error message.
Once it is working successfully, stop the Pleroma daemon and we will interface Pleroma with the web server.</p>
<pre><code>./bin/pleroma stop</code></pre>
<h3>Setup and Configure Nginx</h3>
<p>
Return again to the root user. Let's copy Pleroma's Nginx configuration file from the template given in the installation and enable it:
</p>
<pre><code>cp /opt/pleroma/installation/pleroma.nginx /etc/nginx/sites-available/pleroma.conf
ln -s /etc/nginx/sites-available/pleroma.conf /etc/nginx/sites-enabled/pleroma.conf</code></pre>
<p>Edit the <code>etc/nginx/sites-available/pleroma.conf</code> file and replace <strong>example.tld</strong> with your domain name.</p>
<p>
We now have to get a SSL certificate to enable encryption, since we have a model configuration that already includes SSL information,
just check the brief <a href="standalone.html">the standalone certificate page</a> to get the needed certificate.
Once you've got your cert setup, copy over the Nginx configuration with the below command:
</p>
<p>
Once everything, including your Cerbot certificate is ready, simply reload Nginx with this command:
</p>
<pre><code>systemctl reload nginx</code></pre>
<h3>Setting up the service</h3>
<p>
Pleroma itself runs on a SystemD service similar to other things running on your server like Nginx. To start the service up run the below commands:
</p>
<pre><code>cp /opt/pleroma/installation/pleroma.service /etc/systemd/system/pleroma.service
systemctl start pleroma
systemctl enable pleroma</code></pre>
<p>
If everything worked then when you go to your domain in the web browser you should see a bare-bones Pleroma instance.
</p>
<h3>Creating an Admin User</h3>
<p>You'll be able to create new accounts on the Pleroma instance in the login section on the website but the easiest way to setup an admin account is with the CLI. Simply run the below command replaced with your username:
</p>
<pre><code>su -l pleroma
./bin/pleroma_ctl user new <strong>username</strong> <strong>username</strong>@<strong>example.org</strong> --admin</code></pre>
<p>
If you run into any issues then <a href="https://docs-develop.pleroma.social/backend/installation/otp_en/">feel free to checkout the documentation</a> or send me an email or message. My details are below.
</p>
<ul>
    <li><a href="https://biasedriot.co">biasedriot.co</a></li>
    <li><a href="https://www.youtube.com/channel/UCehh50T6qtDpt_kEUF33GJw">youtube</a></li>
    <li>Bitcoin: <code class=crypto>1Dmn9jEtWAhdLk1HHWkUVNeDdAaBCwNajm</code></li>
    <li>Monero: <code>84Y4FZiTbLeR5qc1fBrBhB1yq5agKtEdoixq2w1ysXJv486MiBCz3czGT15bqeXDPpdLoNyF93inxY3BCk6g8mrDMNKoArS</code></li>
</ul>
    </main>

]]></description>
</item>


<item>
<title>Certbot on Standalone Domains and Subdomains</title>
<guid>https://landchad.net/standalone.html</guid>
<link>https://landchad.net/standalone.html</link>
<pubDate>Fri, 02 Jul 2021 09:14:29 -0400</pubDate>
<description><![CDATA[
    <header><h1>Certbot on Standalone Domains and Subdomains</h1></header>

    <main>
        <p>The command <code>certbot --nginx</code> will take an unencrypted website on an Nginx configuration file, get a certificate for it and change the configuration to use that certificate and thus HTTPS.</p>
        <p>Sometimes, however, you are given an Nginx configuration template that already has encryption/HTTPS, so running the automated <code>certbot --nginx</code> is not possible, as it will simply give an error saying that the certicate that Nginx is looking for doesn't already exist and thus the Nginx config is broken.</p>
        <p>So suppose you want to get a certificate for <strong>pleroma.example.org</strong> because you are installing Pleroma and the configuration file presupposes a certificate.
        In this case you would want to run this:</p>
        <pre><code>systemctl stop nginx
certbot certonly --standalone -d <strong>pleroma.example.org</strong>
systemctl start nginx</code></pre>
        <p>What we do here is temporarily turn of Nginx, then run a <code>certonly</code> subcommand that generates a certificate for the domain without changing or caring about the Nginx configuration. Then we reactivate Nginx, thus turning back on our webserver.</p>
        <p>The reason we deactivate Nginx is that it uses the ports that Certbot will want to bind to, and thus we must temporarily turn Nginx off to let Certbot use those ports. (What it actually does is spin up a dummy webserver that doesn't need to think about the Nginx configuration.)</p>
        <p>This is just a little note of something that might confuse people, but the three commands above should suffice. If your site is still managed by Nginx, it should still be able to renew with simple <code>certbot renew --nginx</code> without a problem.</p>
    </main>

]]></description>
</item>


<item>
<title>Using UFW as a Firewall</title>
<guid>https://landchad.net/ufw.html</guid>
<link>https://landchad.net/ufw.html</link>
<pubDate>Thu, 01 Jul 2021 16:58:11 -0400</pubDate>
<description><![CDATA[
    <header><h1>Using UFW as a Firewall</h1></header>

    <main>
		<p>
			<strong>Uncomplicated Firewall</strong> (UFW) is a front-facing program for the more involved <code>iptables</code> firewall program installed in most GNU/Linux distributions.
			We can use <code>ufw</code> to restrict machines on the internet to only access the services (SSH, websites etc) you want them to, but it can also be used to prevent programs on the computer itself from accesing parts of the internet it shouldn't.
		</p>
		<h2 id="how-to-get-it">How to Get It</h2>
		<p>Log into your server by pulling up a terminal and typing:</p>
		<pre><code>ssh root@<strong>example.org</strong></code></pre>
		<p>
			This command will attempt to log into your server and run a remote shell.
			If you leave the settings default, it should prompt you for your password, and you can just copy or type in the password from Vultr's site.
		</p>
		<p>
        Some VPS providers automatically install <code>ufw</code>, but if you do not have it installed already, install it in the typical way:
		</p>
		<pre><code>apt install ufw</code></pre>
		<h2 id="first-time-setup">First-Time Setup</h2>
		<p>You can check the status of <code>ufw</code> right now by running:</p>
		<pre><code>ufw status</code></pre>
		<p>Without any changes, it should report back <code>Status: inactive</code>. Let's set it up so that only connections to SSH (standardized at port 22) are allowed in, and then enable the firewall:</p>
		<aside>
			<strong>Careful!</strong> Enabling <code>ufw</code> without allowing SSH will block you from remoting to your server.
			Double-check that you have allowed SSH, and if you have changed the default SSH port, put in <em>that</em> number instead.
		</aside>
		<pre><code>ufw default deny incoming # block all incoming connections by default
ufw allow in ssh # or: ufw allow in 22
ufw enable</code></pre>
		<aside>
			<code>ufw</code> has an internal list of protocols applications, and the ports used by them.
			In this case, it knwos SSH is on port 22.
			We'll go more in detail how to view all protocols <code>ufw</code> knows about.
			By default, when you allow an incoming port, it allows that port both on IPv4 and IPv6.
		</aside>
		<p>
			With the firewall enabled and allowing only SSH in, all other ports are prortected from incoming requests.
			To view all your rules, run:
		</p>
		<pre><code>ufw status verbose</code></pre>
		<p>A firewall that allows to connect to SSH and their website may look like:</p>
		<pre><code>Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip
To                           Action      From
--                           ------      ----
22 (SSH)                     ALLOW IN    Anywhere
80,443/tcp (WWW Full)        ALLOW IN    Anywhere
22 (SSH (v6))                ALLOW IN    Anywhere (v6)
80,443/tcp (WWW Full (v6))   ALLOW IN    Anywhere (v6)</code></pre>
		<p>If you want to delete e.g. the 'WWW Full' rule, run:</p>
		<pre><code>ufw delete allow in 'WWW Full'
ufw reload</pre></code>
		<h2 id="enabling-common-services">Enabling Common Services</h2>
		<p>
			You have blocked all incoming ports but SSH, which means no outsiders would be able to access other services, like an email server or your website.
			You should look at the ports your services are open on and enable them individually.
			Here is a list of a few common services:
		</p>
        <h3>Opening Port Numbers</h3>
        <p>Suppose you install <a href="gemini.html">a Gemini server</a>, which must broadcast on port 1965. By default <code>ufw</code> blocks all incoming connections on all ports, so whenever you install a new service like this you will have to tell <code>ufw</code> to enable the desired port:</p>
        <pre><code>ufw allow 1985</code></pre>
		<h3>Websites: HTTP and HTTPS</h3>
        <p>HTTP uses port 80 and HTTPS uses port 443. We can enable them like this:</p>
        <pre><code>ufw allow 80
ufw allow 443</code></pre>
        <p>But <code>ufw</code> additionally knows the typical ports of common serives, so you can also run this:</p>
        <pre><code>ufw allow http
ufw allow https</code></pre>
        <p>And that will do the same thing. There are also other abbreviations for common port lists:</p>
		<pre><code>ufw allow in 'WWW Full'</code></pre>
        <p>To see these other "apps" that <code>ufw</code> knows by default, run <code>ufw app list</code></p>
		<h3>Email: IMAP, POP3, and SMTP</h3>
		<pre><code>ufw allow in IMAPS
ufw allow in POP3
ufw allow in SMTP
ufw allow in 'Postfix SMTPS'
ufw allow in 'Mail Submission'</pre></code>
		<h2 id="fine-tuning-rules">Fine-Tuning Rules</h2>
		<p>Instead of denying all ports by default, you may want to deny (ignores incoming requests) or reject (explicitly tells requests they're not allowed):</p>
		<pre><code>ufw default allow in
ufw deny in <strong>PORT</strong>
ufw reject in <strong>PORT</strong>
ufw reload</code></pre>
		<p>You can add rules to comments to remember what they are there for:</p>
		<pre><code>ufw allow in <strong>PORT</strong> comment 'Secret SSH'
ufw reload
ufw status verbose</code></pre>
		<p>Output:</p>
		<pre><code>To                         Action      From
--                         ------      ----
<strong>PORT</strong>                       ALLOW IN    Anywhere                   # Secret SSH
<strong>PORT</strong> (v6)                  ALLOW IN    Anywhere (v6)              # Secret SSH</pre></code>
		<p>To deny outgoing ports:</p>
		<pre><code>ufw deny out <strong>PORT</strong></code></pre>
		<p>Ratelimiting is useful to protect against brute-force login attacks, like in SSH. Only IPv4 is supported for now. Enable it by running:</p>
		<pre><code>ufw limit <strong>PORT</strong>/tcp</code></pre>
		<p>To blocklist IP addresses:</p>
		<pre><code>ufw deny from <strong>IP_ADDRESS</strong></code></pre>
		<p>To read more what you can do with <code>ufw</code>, run:</p>
		<pre><code>man ufw</code></pre>
		<h2 id="recovering-from-losing-ssh">Recovering SSH</h2>
		<p>
			If you have accidentally firewalled yourself from logging on your computer, you can recover access by using your VPS's virtual console.
            On Vultr, this is on your VPS's menu. To the right of the server name, It is the leftmost icon that looks like a monitor.
		</p>
		<a href="pix/ssh-01.png"><img src="pix/ssh-01.png" alt="View Console"></a>
		<p>Log in through there, and disable ufw by typing:</p>
		<pre><code>ufw disable</code></pre>
		<h2 id="further-reading">Further Reading</h2>
		<ul>
			<li><a href="https://wiki.ubuntu.com/UncomplicatedFirewall">Ubuntu Wiki: UncomplicatedFirewall</a></li>
			<li><a href="https://help.ubuntu.com/community/Gufw">Gufw (Graphical UFW)</a></li>
			<li><code>man ufw</code></li>
		</ul>
		<strong>Contributor</strong> - <a href="https://shunter.xyz">shunter.xyz</a>
    </main>

]]></description>
</item>


<item>
<title>Creating Your Own Chat Server With IRC</title>
<guid>https://landchad.net/irc.html</guid>
<link>https://landchad.net/irc.html</link>
<pubDate>Thu, 01 Jul 2021 16:28:32 -0400</pubDate>
<description><![CDATA[
    <header><h1>Creating Your Own Chat Server With IRC</h1></header>

    <main>
        <img class=titleimg src="pix/irc.svg">
        <p>
          Creating your own chat server for you and your friends is easy, and you don't have to rely on a complicated system to get started.
          IRC is an old but gold protocol, and has clients for basically every operating system made since the 80s, with many powerful modern ones on Linux, Mac, and Windows.
        </p>
        <p>
          Having a chat server for you and your friends makes it impossible for a group of arbitrarily appointed moderators to deplatform you for wrong-think, and gives you greater freedom of communication.
        </p>
        <h2 id="installing">Installing an IRCd</h2>
        <p>
          An IRCd is short for "IRC daemon", which just means an IRC server.
          The most easy IRCd to setup is <a href="https://ergo.chat/">Ergo</a>.
        </p>
        <p>
          The first thing you need to do is create a new user for the server to be run by.
          This is good practice for installing software/servers manually, as it give you more fine-grained control over which permissions the application has.
        </p>
<pre><code>useradd -m ergo -s /bin/bash</code></pre>
        <p>
          Next, we want to switch to our newly created <code>ergo</code> user and create the server directory.
        </p>
<pre><code>sudo -i -u ergo
mkdir server</code></pre>
        <p>
          You can find the latest release of Ergo on its GitHub <a href="https://github.com/ergochat/ergo/releases/latest">latest release</a> page.<br>
          There are several platforms available, but you want to choose Linux, most likely <code>linux-x86_64</code>.<br>
          Once you have selected the correct package, copy its URL and replace <code><i>&lt;release url&gt;</i></code> with the package URL (still as the <code>ergo</code> user):
        </p>
<pre><code>wget https://github.com/ergochat/ergo/releases/download/v2.7.0/ergo-2.7.0-linux-x86_64.tar.gz
tar -xf ergo-2.7.0-linux-x86_64.tar.gz
mv ergo-2.7.0-linux-x86_64/*
rm -r ergo-2.7.0-linux-x86_64*</code></pre>
        <p>Executing <code>ls -l</code> should now yield something like this:</p>
<pre><code>-rw-r--r-- 1 ergo ergo  118825 Jun  8 00:51 CHANGELOG.md
-rw-r--r-- 1 ergo ergo    1983 May 31 01:48 README
-rw-r--r-- 1 ergo ergo   41440 Jun  8 00:42 default.yaml
drwxr-xr-x 2 ergo ergo    4096 Jul  1 09:01 docs
-rwxr-xr-x 1 ergo ergo 9654272 Jun  8 00:53 ergo
-rw-r--r-- 1 ergo ergo    1753 May 31 01:48 ergo.motd
drwxr-xr-x 2 ergo ergo   12288 Jul  1 09:01 languages
-rw-r--r-- 1 ergo ergo   39722 Jun  8 00:42 traditional.yaml</code></pre>
        <p>If you see something similar to the above, that means Ergo is installed, although not quite ready to run yet.</p>
        <h2 id="configuring">Configuring Ergo</h2>
        <p>
          Now that Ergo is installed, you want to configure it to fit the needs of your group.<br>
          The configuration in this section is tailored towards a small group of people, and less for a possibly large network,
          but it should work for any size of group.
        </p>
        <p>
          First thing, make sure you're still using the <code>ergo</code> user, and are in the <code>~/server</code> directory.<br>
          If you aren't, you can run the following to get back there:
        </p>
<pre><code>sudo -i -u ergo
cd ~/server</code></pre>
        <p>
          Next, generate certificate files for TLS:
        </p>
        <pre><code>./ergo mkcerts</code></pre>
        <p>
          Ergo comes with a default configuration file with detailed documentation that can be used to guide you through the configuration process.
          This guide will help you setup the server for a typical use-case, but if you see any settings that you would like to change along the way,
          go ahead and change them, as long as you know what you're doing.
        </p>
        <p>To start configuring, we need to copy some files:</p>
<pre><code>cp default.yaml ircd.yaml
cp ergo.motd ircd.motd</code></pre>
        <p>
          The next steps involve editing the newly copied <code>ircd.yaml</code> file. If you do not know how to edit text files from the comment line,
          you can use <code>nano</code>, which is very simple, using arrow keys to navigate, <code>CTRL+O</code> to save, and <code>CTRL+X</code> to exit.<br>
          Another option is <code>vim</code>, which is a much more powerful text editor, but has a learning curve. It is only recommended for this guide if you already know it.<br>
          Lastly, you can copy the <code>ircd.yaml</code> file to a text editor on your computer and edit it with a GUI text editor of your choice.
          If that is what you choose to do, you may want to just download the file from <a href="https://raw.githubusercontent.com/ergochat/ergo/master/default.yaml">Ergo's GitHub</a>,
          edit it on your computer, clear the <code>ircd.yaml</code> file on the server, and then paste the contents from your computer into the blank file.<br>
          No matter how you do it, the next steps assume you can edit the configuration file.
        </p>
        <p>
          <b>Note</b>:<br>
          The options highlighted in this section are not a complete overview of all options.
          Instead, the options shown are the ones which are most relevant to a small network.<br>
          You should read over the configuration file yourself if you are curious about everything you can change.
        </p>
        <h3 id="configuring-names">Network and server names</h3>
        <p>
          One of the first properties in the config file is network name.
          You can change this to whatever you like, as it will show up as the name when you connect to the server.
        </p>
<pre><code># network configuration
network:
    # name of the network
    name: "Land-Chat"</code></pre>
        <p>Change the server name to your server's domain name.</p>
<pre><code># server configuration
server:
    # server name
    name: "example.org"</code></pre>
        <h3 id="configuring-password">Network password</h3>
        <p>
          The next step is optional, depending on if you want your network password protected or not.
          The benefit of password protection is fairly obvious; nobody can connect to your network unless you gave them the password.
          If you're wanting to run a public network which anyone can join and create a channel, you want to skip this, but for personal setups,
          it is highly recommended.
        </p>
        <p>Generate a password to use by executing the following:</p>
        <pre><code>./ergo genpasswd</code></pre>
        <p>
          It will ask you to enter a password and confirm it, then you will be given a hashed password.<br>
          Copy this password, and paste it into the following field (also removing the <code>#</code> before the <code>password:</code> line):
        </p>
<pre><code># password to login to the server, generated using `ergo genpasswd`:
password: "<i>&lt;your hashed password&gt;</i>"</code></pre>
        <h3 id="configuring-motd">Message of the day (MotD)</h3>
        <p>Change the MotD (<b>M</b>essage <b>o</b>f <b>t</b>he <b>D</b>ay) file to the one you copied earlier:</p>
<pre><code># motd filename
# if you change the motd, you should move it to ircd.motd
motd: ircd.motd</code></pre>
        <p>Feel free to edit <code>ircd.motd</code> to your heart's content. Its contents will be sent to clients when they connect to the network.</p>
        <h3 id="configuring-ip-limits">IP limits</h3>
        <p>
          For security purposes, you might want to limit the amount of client connections per IP.
          For a private network, 4 is likely the maximum amount of connections you will have per IP, so that is a safe value.<br>
          If your network is password protected, this is less of an issue, since the only people connecting will be people who have the password.
          The following is the default, but you can change it to be whichever value you like:
        </p>
<pre><code># IP-based DoS protection
ip-limits:
    # whether to limit the total number of concurrent connections per IP/CIDR
    count: true
    # maximum concurrent connections per IP/CIDR
    max-concurrent-connections: 16</code></pre>
        <h3 id="configuring-ip-cloaking">IP cloaking</h3>
        <p>
          Traditionally, IRC networks expose users' IP addresses to everyone. This is not a good practice for privacy, however.
          With Ergo, IP cloaking is enable by default. You can enable or disable it if you like, and change how it looks to users.<br>
          In this case, <code>netname</code> was changed to <code>"chad"</code>.
        </p>
<pre><code># IP cloaking hides users' IP addresses from other users and from channel admins
# (but not from server admins), while still allowing channel admins to ban
# offending IP addresses or networks. In place of hostnames derived from reverse
# DNS, users see fake domain names like pwbs2ui4377257x8.irc. These names are
# generated deterministically from the underlying IP address, but if the underlying
# IP is not already known, it is infeasible to recover it from the cloaked name.
# If you disable this, you should probably enable lookup-hostnames in its place.
ip-cloaking:
    # whether to enable IP cloaking
    enabled: true
    # whether to use these cloak settings (specifically, `netname` and `num-bits`)
    # to produce unique hostnames for always-on clients. you can enable this even if
    # you disabled IP cloaking for normal clients above. if this is disabled,
    # always-on clients will all have an identical hostname (the server name).
    enabled-for-always-on: true
    # fake TLD at the end of the hostname, e.g., pwbs2ui4377257x8.irc
    # you may want to use your network name here
    netname: "chad"</code></pre>
        <h3 id="configuring-hexchat-password">Password enforcement adjustments for HexChat (and possibly other clients)</h3>
        <p>
          Ergo offers account registration to allow users to do things like use history and bouncer features, register channels, etc.<br>
          In clients such as HexChat, server password may conflict with account passwords, so the following setting should be enable if you wish to use accounts with clients such as HexChat.<br>
          Note that this could under some circumstances be considered a security hazard, as a user with an account does not need to know the server password to connect,
          although that user would have needed to register an account before the server had a password, and then a password would need to have been set after the fact, so this can be considered a very small concern if your setup always has had a password.<br>
          Also keep in mind that this setting has no effect if your network does not even have a password at all.
        </p>
<pre><code># some clients (notably Pidgin and Hexchat) offer only a single password field,
# which makes it impossible to specify a separate server password (for the PASS
# command) and SASL password. if this option is set to true, a client that
# successfully authenticates with SASL will not be required to send
# PASS as well, so it can be configured to authenticate with SASL only.
skip-server-password: true</code></pre>
        <h3 id="configuring-multiclient">Multiclient, always-on clients, history, etc</h3>
        <p>
          Traditionally, IRC servers have no message history, and once you close your client, you cannot receive messages, and are not shown to be online at all.
          Ergo includes functionality to allow users to both receive history, and keep their clients "online" even after they have left.
          It also allows multiple clients to connect to the same account.<br>
          If you are running a private network for friends, you should set <code>always-on</code> and <code>auto-away</code> to <code>opt-out</code>,
          to have all users with accounts to appear as if they are online at all times, and be able to receive messages when they are offline.<br>
          For a public network, keep everything as their default values, since you probably do not want randoms having this by default.<br>
          If for some reason you do not want any of these features at all, you can set <code>enabled</code> to <code>false</code>, but this is not recommended.
          Below are the recommended values for a private network (e.g. for friends) where users with accounts will be able to receive messages and history while they are offline.
        </p>
<pre><code># multiclient controls whether Ergo allows multiple connections to
# attach to the same client/nickname identity; this is part of the
# functionality traditionally provided by a bouncer like ZNC
multiclient:
    # when disabled, each connection must use a separate nickname (as is the
    # typical behavior of IRC servers). when enabled, a new connection that
    # has authenticated with SASL can associate itself with an existing
    # client
    enabled: true
    # if this is disabled, clients have to opt in to bouncer functionality
    # using nickserv or the cap system. if it's enabled, they can opt out
    # via nickserv
    allowed-by-default: true
    # whether to allow clients that remain on the server even
    # when they have no active connections. The possible values are:
    # "disabled", "opt-in", "opt-out", or "mandatory".
    always-on: "opt-out"
    # whether to mark always-on clients away when they have no active connections:
    auto-away: "opt-out"
    # QUIT always-on clients from the server if they go this long without connecting
    # (use 0 or omit for no expiration):
    #always-on-expiration: 90d</code></pre>
        <h3 id="configuring-vhosts">VHosts</h3>
        <p>
          IP cloaking was mentioned previously, and somewhat related to that, Ergo includes "vhost" functionality, which allows users to set a custom IP/host string.
          This is mostly for cosmetic value, and does not interfere with operators being able to see actual IP addresses for banning, but if you do not want it enable for some reason, you can disable it.
        </p>
<pre><code># vhosts controls the assignment of vhosts (strings displayed in place of the user's
# hostname/IP) by the HostServ service
vhosts:
    # are vhosts enabled at all?
    enabled: true</code></pre>
        <h3 id="configuring-channels">Channels</h3>
        <p>
          Channels are where everyone on an IRC network talk. By default, anyone can create a channel, and anyone with an account can register one.
          The difference between a normal channel and a registered one is that the registered one will preserve the operator status of the person who created,
          whereas a normal channel's owner will lose operator status if they leave the channel or disconnect from the network.<br>
          There are various settings for channels available, but the defaults are suitable for a private network with trust among users, or where you just want anyone to have the ability to create a channel.
          Below are the default values:
        </p>
<pre><code># channel options
channels:
    # modes that are set when new channels are created
    # +n is no-external-messages and +t is op-only-topic
    # see  /QUOTE HELP cmodes  for more channel modes
    default-modes: +nt
    # how many channels can a client be in at once?
    max-channels-per-client: 100
    # if this is true, new channels can only be created by operators with the
    # `chanreg` operator capability
    operator-only-creation: false
    # channel registration - requires an account
    registration:
        # can users register new channels?
        enabled: true
        # restrict new channel registrations to operators only?
        # (operators can then transfer channels to regular users using /CS TRANSFER)
        operator-only: false
        # how many channels can each account register?
        max-channels-per-account: 15</code></pre>
        <h3 id="configuring-operators">Operators (administrators, etc)</h3>
        <p>
          The IRC term for an administrator or another privileged user is "operator", or "oper" for short.<br>
          Ergo's opers have different permissions that can be granted to them, and are defined in "classes", basically groups of permissions under a name.
          For example, "chat-moderator" and "server-admin" are defined in the default configuration:
        </p>
<pre><code># operator classes
oper-classes:
    # chat moderator: can ban/unban users from the server, join channels,
    # fix mode issues and sort out vhosts.
    "chat-moderator":
        # title shown in WHOIS
        title: Chat Moderator
        # capability names
        capabilities:
            - "kill"
            - "ban"
            - "nofakelag"
            - "roleplay"
            - "relaymsg"
            - "vhosts"
            - "sajoin"
            - "samode"
            - "snomasks"
    # server admin: has full control of the ircd, including nickname and
    # channel registrations
    "server-admin":
        # title shown in WHOIS
        title: Server Admin
        # oper class this extends from
        extends: "chat-moderator"
        # capability names
        capabilities:
            - "rehash"
            - "accreg"
            - "chanreg"
            - "history"
            - "defcon"
            - "massmessage"</code></pre>
        <p>
          The above can be kept with their default values, but you are free to modify them or create any new classes that are appropriate for your setup.<br>
          Next, let's actually create an operator account:
        </p>
<pre><code># ircd operators
opers:
    # default operator named 'gigachad'; log in with /OPER gigachad &lt;password&gt;
    "gigachad":
        # which capabilities this oper has access to
        class: "server-admin"
        # custom whois line
        whois-line: is the server administrator
        # custom hostname
        vhost: "gigachad"
        # normally, operator status is visible to unprivileged users in WHO and WHOIS
        # responses. this can be disabled with 'hidden'. ('hidden' also causes the
        # 'vhost' line above to be ignored.)
        hidden: false
        # modes are modes to auto-set upon opering-up. uncomment this to automatically
        # enable snomasks ("server notification masks" that alert you to server events;
        # see `/quote help snomasks` while opered-up for more information):
        #modes: +is acjknoqtuxv
        # operators can be authenticated either by password (with the /OPER command),
        # or by certificate fingerprint, or both. if a password hash is set, then a
        # password is required to oper up (e.g., /OPER dan mypassword). to generate
        # the hash, use `ergo genpasswd`.
        password: "<i>&lt;your oper password&gt;</i>"</code></pre>
        <p>
          This is a modified version of the default oper entry. The account name is "gigachad", but you can change it to anything.<br>
          Replace <code><i>&lt;your oper password&gt;</i></code> with a password generated by <code>./ergo genpasswd</code>, and you will have a new oper account to use.<br>
          Note that to log into an oper account, clients have to enter <code>/OPER <i>&lt;oper name&gt;</i> <i>&lt;oper password&gt;</i></code> each time they log in.
          This can be automated by most clients by setting the command to be executed when the client logs in.
          In the case of HexChat, you can edit your network and add the command to the <code>Connect commands</code> tab of the menu.<br>
          You can copy everything from <code>"gigachad"</code> to the end of the line, paste it again, and change the name to create another oper account.
          Another, less privileged example of an oper is shown as a comment below the above configuration snippet.
        </p>
        <h3 id="configuring-history">Chat history</h3>
        <p>
          Traditionally, IRC networks do not store, relay, or handle chat history in any way.<br>
          On a privacy standpoint, this is a good thing, since chats are entirely ephemeral and handled by clients.<br>
          On a practicality standpoint, this is a bad thing, since people have to keep a client connected 24/7 to see message history.<br>
          For normalfriends, this can be a big problem, not only because having to stay online 24/7 is just annoying or infeasible,
          but also because they are likely used to chat platforms that handle history for them.<br>
          With this in mind, enabling history is a good idea if you want to move friends over to IRC, and will make things a lot more pleasant for private networks.
        </p>
        <p>
          Ergo's <code>history</code> configuration group is very long, so it is encouraged to read over it yourself.
          This section will go over the most important pieces of that configuration group.
        </p>
        <p>
          History is not endless (unless you want it to be), and the amount that can be stored for channels is configurable:
        </p>
<pre><code># how many channel-specific events (messages, joins, parts) should be tracked per channel?
channel-length: 2048</code></pre>
        <p>
          History is already enabled by default, but that just means it is being collected, not relayed by default.
          To relay history to clients when they connect, change the following to the amount of messages that you think is appropriate:
        </p>
<pre><code># number of messages to automatically play back on channel join (0 to disable):
autoreplay-on-join: 250</code></pre>
        <p>
          History older than a certain time can be configured to be deleted or be inaccessible.
          The default cutoff time is 1 week, but this is configurable as well.
        </p>
<pre><code>
# options to delete old messages, or prevent them from being retrieved
restrictions:
    # if this is set, messages older than this cannot be retrieved by anyone
    # (and will eventually be deleted from persistent storage, if that's enabled)
    expire-time: 1w
</code></pre>
        <p>
          By default, Ergo only stores chat history in memory, so when the server restarts, all history is lost.
          If you wish to have chat history persist beyond restarts, you must store it in a MySQL database:
        </p>
<pre><code># options to store history messages in a persistent database (currently only MySQL).
# in order to enable any of this functionality, you must configure a MySQL server
# in the `datastore.mysql` section.
persistent:
    enabled: true
    # store unregistered channel messages in the persistent database?
    unregistered-channels: true</code></pre>
<br>
<pre><code># connection information for MySQL (currently only used for persistent history):
mysql:
    enabled: false
    host: "localhost"
    port: 3306
    # if socket-path is set, it will be used instead of host:port
    #socket-path: "/var/run/mysqld/mysqld.sock"
    user: "ergo"
    password: "hunter2"
    history-database: "ergo_history"
    timeout: 3s
    max-conns: 4
    # this may be necessary to prevent middleware from closing your connections:
    #conn-max-lifetime: 180s</code></pre>
        <p>
          For privacy reasons, you may want to allow users to delete their own messages in history, or export their messages to JSON:
        </p>
<pre><code># options to control how messages are stored and deleted:
retention:
    # allow users to delete their own messages from history?
    allow-individual-delete: true
    # if persistent history is enabled, create additional index tables,
    # allowing deletion of JSON export of an account's messages. this
    # may be needed for compliance with data privacy regulations.
    enable-account-indexing: true</code></pre>
        <h3 id="configuring-spam">Spam reduction</h3>
        <p>
          Most IRC networks have measures in place to reduce chat spam. By default, "fakelag" is enabled in Ergo, and that can deal with most aggregious chat spam.<br>
          If you are running a private network where user trust is high, you can disable it so that there are no limits on the speed that messages can be sent.
        </p>
<pre><code># fakelag: prevents clients from spamming commands too rapidly
fakelag:
    # whether to enforce fakelag
    enabled: true
    # time unit for counting command rates
    window: 1s
    # clients can send this many commands without fakelag being imposed
    burst-limit: 5
    # once clients have exceeded their burst allowance, they can send only
    # this many commands per `window`:
    messages-per-window: 2
    # client status resets to the default state if they go this long without
      # sending any commands:
    cooldown: 2s</code></pre>
        <h2 id="using">Starting and using your server</h3>
        <p>
          Now that Ergo is both installed and configured, you can actually start using it!
        </p>
        <h3 id="using-starting">Starting the server</h3>
        <p>
          First thing, make sure you're still using the <code>ergo</code> user, and are in the <code>~/server</code> directory.<br>
          If you aren't, you can run the following to get back there:
        </p>
<pre><code>sudo -i -u ergo
cd server</code></pre>
        <p>
          Starting the server is done in one command:
        </p>
        <pre><code>./ergo run</code></pre>
        <p>
          It will stay online until you close the terminal, or press CTRL+C. Don't worry, the next section goes over how to make it run like a normal server with a SystemD service.<br>
          If you have not already, make sure the port <code>6697</code> is not blocked on your server. If you are using UFW as your firewall,
          you need to run <code>ufw enable 6697</code> (not as the <code>ergo</code> user, of course).<br>
          If you make and configuration changes while the server is running, you can apply them without restarting by typing <code>/rehash</code> as an operator.
        </p>
        <h3 id="using-connecting">Connecting to the server</h3>
        <p>
          To use IRC, you of course need an IRC client. There are many choices available, but the most widely used for Windows and Linux is <a href="https://hexchat.github.io/">HexChat</a>.
          On Mac, you have a slightly nicer option with <a href="https://www.codeux.com/textual/">Textual</a>, although you have to <a href="https://github.com/Codeux-Software/Textual/#building-textual">compile it from source</a> if you want to use it for free.<br>
          A more user-friendly and modern client choice is TheLounge, which is explained in the last section of this guide, if you want to look into it.
        </p>
        <p>
          Connecting with HexChat is very easy. When you start it, you will see something like this:
        </p>
        <img src="pix/irc/hexchat-network-select.png" alt="HexChat network select">
        <p>
          From there, you should click <code>+ Add</code> and name the server whatever you like (so you can find it on the server list).<br>
          Once you have created a new server and named it, select it and click <code>Edit...</code>.
          A menu will show up like the one below. Change the domain to whatever domain your server is running on,
          and make sure to put in your server password if you set one.
        </p>
        <img src="pix/irc/hexchat-network-edit.png" alt="HexChat network edit menu">
        <p>
          Once you're done editing the network, click <code>(X) Close</code>, select your network from the network list, and click <code>Connect</code>.<br>
          If all is well, you should be connected!
        </p>
        <img src="pix/irc/hexchat-connection-complete.png" alt="HexChat connection complete">
        <p>
          The process is very similar on Textual.<br>
          Create a new network and connect to it. Note that it will ask if you want to connect even though the certificate is unsigned.
          This is due to the self-signed certificates generated for the server, and is not a problem or security vulnerability, it is just a little annoying.
        </p>
        <img src="pix/irc/textual-network-edit.png" alt="Textual network edit menu">
        <h2 id="service">Surviving restarts with a SystemD service</h3>
        <p>
          In the beginning of the last section, Ergo was started by simply running <code>./ergo run</code>, but this is only suitable for testing.
          To have a proper server setup, you need to run it as a service. This can be achieved via a SystemD service.
        </p>
        <p>
          Before creating your service file, make sure you are in <code>~/server</code> as the <code>ergo</code> user.<br>
          Once you have done that, create a file called <code>start.sh</code> with the following content:
        </p>
<pre><code>#!/bin/bash
./ergo run</code></pre>
        <p>Save the file, then mark it as executable:</p>
        <pre><code>chmod +x start.sh</code></pre>
        <p>Now, create a file called <code>ergo.service</code> with the following content:</p>
<pre><code>[Unit]
Description=Ergo IRC server
After=network.target
# If you are using MySQL for history storage, comment out the above line
# and uncomment these two instead (you must independently install and configure
# MySQL for your system):
# Wants=mysql.service
# After=network.target mysql.service
[Service]
Type=simple
User=ergo
WorkingDirectory=/home/ergo/server
ExecStart=/home/ergo/server/start.sh
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
LimitNOFILE=1048576
# Uncomment this for a hidden service:
# PrivateNetwork=true
[Install]
WantedBy=multi-user.target</code></pre>
        <p>
          You now have your service file, but it is not installed yet.
          To install it, switch to your normal user, and execute the following lines to install, enable, and start the SystemD service:
        </p>
<pre><code>ln -s /home/ergo/server/ergo.service /etc/systemd/system/ergo.service
systemctl enable ergo
systemctl start ergo</code></pre>
        <p>Ergo is now installed and running as a service, and will automatically start when the system boots.</p>
        <h2 id="registering">Registering accounts and channels</h2>
        <p>
          Account and channel registration were mentioned multiple times in this guide, and are indeed very important parts of the modern IRC ecosystem.
          You can connect to most IRC networks and talk without creating an account, but you will not be able to reserve your nickname or register channels, so it is important to register an account.
        </p>
        <h3 id="registering-accounts">Registering an account with NickServ</h3>
        <p>
          First, make sure you are connected to your IRC network.
          Once you are, type <code>/nickserv help</code> to make sure NickServ (the registration system) is working propertly.<br>
          If all is well, type the following, replacing <code><i>&lt;your password&gt;</i></code> with the password you want to use:
        </p>
        <pre><code>/nickserv register <i>&lt;your password&gt;</i></code></pre>
        <p>
          At this point, you are now registered!<br>
          The final step is to configure authentication with your client.
        </p>
        <p>In HexChat, all that needs to be done is changing <code>Login method</code> to <code>SASL (username + password)</code>, and entering your NickServ password that you used earlier into the password field:</p>
        <img src="pix/irc/hexchat-sasl.png" alt="HexChat SASL in network edit menu">
        <p>
          In Textual, open up your network in the menu, and click <code>Identity</code> under <code>Server Properties</code>.
          Enter your password in <code>Personal Password</code>, and check <code>Wait for identification before joining channels</code>.
        </p>
        <img src="pix/irc/textual-identity.png" alt="Textual identity menu">
        <p>You will now be logged into your account when you connect to your network.</p>
        <h3 id="registering-channels">Registering channels with ChanServ</h3>
        <p>
          Once you have an account registered, you can register channels with ChanServ.<br>
          To do so, join the channel you want to register, then type the following, replacing <code><i>&lt;your channel&gt;</i></code> with the name of the channel you want to register:
        </p>
        <pre><code>/chanserv register #<i>&lt;your channel&gt;</i></code></pre>
        <p>
          You are now the channel owner, and are free to appoint operators, administrators, etc for it.
          When you go offline, you won't lose ownership, and you cannot be removed as the owner unless you unregister the channel later.
        </p>
        <h2 id="moderation">Moderation</h2>
        <p>
          Like any chat, there will come a point where you need to use moderation tools to keep things under control.
          Many IRC setup guides do not go over moderation, so it can be stressful when operators need to actually use moderation tools.<br>
          The main difference between IRC and other chat systems in terms of moderation is the difference between channel bans and network bans.
          Channel ban keeps a person out of channel a channel, whereas a network ban keeps a person out of the entire network.
        </p>
        <h3 id="moderation-masks">Understanding masks</h3>
        <p>
          Bans are applied "masks", which are formatted pieces of text that contain a user's nick (username), their realname value, and their IP address or host.<br>
          This is what a mask looks like: <code>nick!~nick-dude@127.0.0.1</code>.<br>
          In bans, asterisks can be used as wildcards, which is useful for banning IP address ranges, patterns of nicknames, or whatever else you can think of.<br>
          A ban on the nick <code>person</code>, for example, would look like this: <code>person!*@*</code>.<br>
          A ban on anyone with the IP address <code>127.0.0.1</code> would look like this: <code>*!*@127.0.0.1</code>
        </p>
        <h3 id="moderation-real-ips">Discovering real IPs</h3>
        <p>
          Even if IP cloaking is enabled on your network, you can still obtain real IP addresses/hosts if you are an operator.
          See the <b>Operators</b> part of the configuration section of this guide on how to become an operator.<br>
          To find out a user's real IP, simply type <code>/whois</code> along with the user's nick, and you will see information about the user, along with their real IP address/host.<br>
          <code>/whois</code> is not a command that is exclusive to operators, but it does not reveal as much information to non-operators.
        </p>
        <h3 id="moderation-network-ban">Banning someone from the network</h3>
        <p>
          Any netword-wide moderation action requires being an operator. See the <b>Operators</b> part of the configuration section of this guide on how to become an operator.<br>
          Banning someone from the network is achieved with the <code>/kline</code> command. To see more info on the command, type <code>/helpop kline</code>.<br>
        </p>
        <p>To ban a nick from the network:</p>
        <pre><code>/kline andkill <i>&lt;nick&gt;</i>!*@*</code></pre>
        <p>To ban an IP address or host from the network:</p>
        <pre><code>/kline andkill *!*@<i>&lt;IP or mask&gt;</i></code></pre>
        <p>To unban a mask, you can use the <code>/unkline</code> command with the mask you want to unban.</p>
        <h3 id="moderation-channel-ban">Banning someone from a channel</h3>
        <p>
          Channel owners, administrators, and operators can ban people from channels.
          This is not the same as banning someone from the network, since it only has an effect on one channel.
          Additionally, a channel operator is not the same as a network operator.
        </p>
        <p>To ban someone in a channel, type the following in that channel, replacing <code><i>&lt;mask&gt;</i></code> with the user's mask:</p>
        <pre><code>/mode +b <i>&lt;mask&gt;</i></code></pre>
        <p>
          Note that this will only ban the user, not kick them immediately.
          You will want to run <code>/kick</code> along with the user's nick to also kick them.<br>
          To unban a user, run the command above, but replace the <code>+</code> with a <code>-</code>.<br>
          You can see who is banned in a channel by typing <code>/banlist</code>.
        </p>
        <h3 id="moderation-muting">Muting people in a channel</h3>
        <p>
          By default, anyone can speak in an IRC channel. To change this, you must be a channel owner, administrator, or operator.<br>
          Channels, along with users, have modes, which modify their behavior. There is a special mode for channels called <code>m</code> (moderated) which requires users to be privileged in some way to talk.<br>
          To set a channel as moderated, type the following in the channel:
        </p>
        <pre><code>/mode +m</code></pre>
        <p>
          Now, users must be an owner, administrator, operator, or be voiced to talk in the channel
          This be reversed by typing the command above, but changing the <code>+</code> to a <code>-</code>.<br>
          To voice a user, run the following, replacing <i>&lt;nick&gt;</i> with the user's nick:
        </p>
        <pre><code>/mode +v <i>&lt;nick&gt;</i></code></pre>
        <p>Unvoice the user by typing the above command, but replacing the <code>+</code> with a <code>-</code>.</p>
        <h3 id="moderation-appointing">Appointing channel administrators and operators</h3>
        <p>
          Assuming you a channel owner, you can appoint both administrators and operators.
          If you are only an operator, you may only appoint operators.<br>
          The difference between administrator and operator is mainly that administrators cannot have their privileges taken away by operators, only owners.
          To appoint an administrator, type the following, replacing <i>&lt;nick&gt;</i> with the user's nick:
        </p>
        <pre><code>/mode +a <i>&lt;nick&gt;</i></code></pre>
        <p>To appoint an operator, type the following, replacing <i>&lt;nick&gt;</i> with the user's nick:</p>
        <pre><code>/mode +o <i>&lt;nick&gt;</i></code></pre>
        <p>
          You can also use <code>/op</code> and <code>/deop</code> on most clients to appoint and remove an operator.<br>
          To remove administrator or operator status, run either of the above commands, but replace the <code>+</code> with a <code>-</code>.
        </p>
        <h2 id="thelounge">Bringing modern-day features to IRC with TheLounge</h3>
        <p>
          A large downside to IRC as a protocol is just how old it is, and the limitations that exist because of it.
          Other old protocols such as HTTP were built to be content-agnostic and versitile, but IRC was built with a very specific set of features, so it has not held up so well to contemporary chat systems.<br>
          A notable thing that IRC as a protocol is missing is file uploads, and other fancy features that many other chats have.<br>
          With that said, these problems can be fixed by clients, although many clients are still very primitive.
        </p>
        <p>
          <a href="https://thelounge.chat/">TheLounge</a> is a modern self-hosted IRC web client that tries to make IRC as user-friendly as possible.
          It can be the answer to many of the complaints that normalfriends may have about IRC. It runs on anything with a web browser, can be "installed" since it is a PWA (Progressive Web App),
          and is optimized for both desktops and mobile devices. It keeps you logged in even when you are gone, and even supports file uploads and embeds.<br>
          Effectively, it brings IRC up to the standard of most other chat systems.
        </p>
        <p>
          If you would like to setup an instance of TheLounge for you and your friends, you can take a look at their <a href="https://thelounge.chat/docs/install-and-upgrade">installation guide</a>.<br>
          It is a self-hosted web app, so you can run it for multiple people, not just yourself.
        </p>
        <hr>
        <p><i>Written by <a href="https://termer.net/">Termer</a></i></p>
    </main>

]]></description>
</item>


<item>
<title>Setting up Gitea</title>
<guid>https://landchad.net/gitea.html</guid>
<link>https://landchad.net/gitea.html</link>
<pubDate>Thu, 01 Jul 2021 16:14:22 -0400</pubDate>
<description><![CDATA[
    <header><h1>Setting up Gitea</h1></header>

    <main>
        <img class=titleimg src="pix/gitea.svg">
        <p>Gitea allows you to self-host your git repositories similar to <a href="git.html">bare repositories</a>, but comes with additional features that you might know from GitHub, such as issues, pull requests or multiple users. Its advantage over GitLab&mdash;another Free Software GitHub clone&mdash;is that it is much more lightweight and easier to setup.</p>
        <p>Head over to <a href="https://gitea.com">gitea.com</a> to see what it looks like in practice.</p>
        <p>Although Gitea is lighter than Gitlab, if you have a VPS with only 512MB of RAM, you will probably have to upgrade. Gitea is more memory-intensive than having just a bare git repository.</p>
        <h2>Installing Gitea</h2>
        <p>First install a few dependencies:</p>
        <pre><code>apt install curl sqlite3</code></pre>
        <p>Unfortunately, Gitea itself is not in the official Debian repos, so we will add a third-party repository for it.</p>
        <p>Add the repo's gpg key to apt's trusted keys:</p>
        <pre><code>curl -sL -o /etc/apt/trusted.gpg.d/morph027-gitea.asc https://packaging.gitlab.io/gitea/gpg.key</code></pre>
        <p>Then add the actual repository to apt:</p>
        <pre><code>echo "deb [arch=amd64] https://packaging.gitlab.io/gitea gitea main" > /etc/apt/sources.list.d/morph027-gitea.list</code></pre>
        <p>Now we can install Gitea:<p>
        <pre><code>apt update
apt install gitea</code></pre>
        <p>Since apt automatically enables and starts the Gitea service, it should already be running on port <code>3000</code> on your server!</p>
        <h2>Setting up a Nginx reverse proxy</h2>
        <p>You should know how to generate SSL certificates and use Nginx by now. Add this to your Nginx config to proxy requests made to your git subdomain to Gitea running on port 3000:</p>
        <pre><code>
server {
	listen 443 ssl;
	listen [::]:443 ssl;
        ssl_certificate /etc/ssl/nginx/<strong>git.example.org</strong>.crt;
        ssl_certificate_key /etc/ssl/nginx/<strong>git.example.org</strong>.key;
        server_name <strong>git.example.org</strong>;
	location / {
		proxy_pass http://localhost:3000/; # The / is important!
		proxy_redirect off;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
	}
}
        </pre></code>
        <p>And reload Nginx:</p>
        <pre><code>systemctl reload nginx</code></pre>
        <h2>Setting up Gitea</h2>
        <p>If everything worked fine you should now see a setup screen when you go to your configured domain in the browser. The options should be pretty self-explanatory, it is only important to select SQLite3 and to replace the base url and SSH server domain with your own.</p>
        <dl>
            <dt>Database Type:</dt>
            <dd>SQLite3</dd>
            <dt>SSH Server Domain:</dt>
            <dd><strong>git.example.org</strong></dd>
            <dt>Gitea Base URL:</dt>
            <dd><strong>git.example.org</strong></dd>
        </dl>
        <p>These and other settings can be changed in a configuration file later so don't worry about making wrong decisions right now.</p>
        <p>After clicking the install button you should now be able to log into your Gitea instance with the account you just created! Explore the settings for more things to do, such as setting up your SSH keys.</p>
        <p>If Gitea does not load fully and has random errors, it is possible that you need to increase your available memory on your VPS. This can usually be done on your VPS-provider's website without too much trouble.</p>
        <h2>A few extras</h2>
        <h3>Automatically create a new repo on push</h3>
        <p>This is an incredicly useful feature for me. Open up <code>/etc/gitea/app.ini</code> and add <code>DEFAULT_PUSH_CREATE_PRIVATE = true</code> to the <code>repository</code> section like so:</p>
        <img src=pix/gitea-push-create.png>
        <br>
        <p>If you now add a remote to a repository like this</p>
        <pre><code>git remote add origin 'ssh://gitea@git.<strong>example.org</strong>/<strong>username</strong>/<strong>coolproject</strong>.git'</code></pre>
        <p>and push, Gitea will automatically create a private <code>coolproject</code> repository in your account!</p>
        <h3>Change tab-width</h3>
        <p>By default Gitea displays tabs 8 spaces wide, however I prefer 4 spaces. We can change this!</p>
        <pre><code>mkdir -p /var/lib/gitea/custom/templates/custom/</code></pre>
        <p>And write this into <code>/var/lib/gitea/custom/templates/custom/header.tmpl</code>:</p>
        <pre><code>&ltstyle&gt
.tab-size-8 {
	tab-size: 4 !important;
	-moz-tab-size: 4 !important;
}
&lt/style&gt</code></pre>
        <h2>Contribution</h2>
        <ul>
            <li><a href="https://phire.cc">phire</a></li>
        </ul>
    </main>

]]></description>
</item>


<item>
<title>Hosting Your Own Git Repositories</title>
<guid>https://landchad.net/git.html</guid>
<link>https://landchad.net/git.html</link>
<pubDate>Thu, 01 Jul 2021 07:19:51 -0400</pubDate>
<description><![CDATA[
    <header><h1>Hosting Your Own Git Repositories</h1></header>

    <main>
        <img class=titleimg src="pix/git.svg">
        <p>
        Once you have your own VPS or other Internet-available server, you can
        start hosting your own git repositories. The goal of this tutorial is
        for you to go from</p>
        <pre><code>git clone github.com/...</code></pre>
        <p>to</p>
        <pre><code>git clone YourLandChadDomainName.xyz/...</code></pre>
        <p>
        so you can cultivate your own homegrown, grass-fed code, rather than
        relying on a centralized proprietary service like GitHub.
        </p>
        <h2>Installing git</h2>
        <p>
        You most likely already have it installed on your server, but if not,
        run:</p>
        <pre><code>apt install git</code></pre>
        <p>
        We don't need any additional software, <code>git</code> itself ships
        with everything needed to host a remote repository!
        </p>
        <h2>Creating bare repositories</h2>
        <p>
        For each repository you want to host, you will need to manually create
        what's called a "bare" repository on your server. These hold all the
        commits and any other git data needed for your repository, but without
        an expanded "index" in which you can just browse all the files of a
        certain commit in the file system.
        </p>
        <p>
        These repositories need to be owned by the <code>git</code> user, and
        you should probably pick a directory where you will store them all. One
        sane choice is under <code>/srv/git/</code>, and we will use this as the
        example directory for the rest of the tutorial, but any other path will
        do as well.
        </p>
        <h3>Become the git user and create the directory</h3>
        <p>
        If you're logged in to your server as root and have <code>git</code>
        installed, you can become the <code>git</code> user by executing
        </p>
        <pre><code>su git</code></pre>
        <p>
        Now navigate to/create your desired directory, for example
        </p>
        <pre><code>cd /srv
mkdir git</code></pre>
        <h3>Create the repo</h3>
        <p>
        Now you can create the bare repository with
        </p>
        <pre><code>git init --bare my-repo.git</code></pre>
        <p>
        By convention, bare repository names end with ".git".
        </p>
        <p>
        Repeat the above command for any other repositories you want to host.
        </p>
        <h2>Syncing local repositories with your server</h2>
        <h3>Set up SSH login for the git user</h3>
        <p>
        You will need to be able to login remotely via <code>ssh</code> as the
        <code>git</code> user we've used before. To do this, you will either
        need to set up a password for the <code>git</code> user by running
        <code>passwd git</code>,
        or copy your public SSH key from your local machine to
        <code>/home/git/.ssh/authorized_keys</code>.
        See the <a href="sshkeys.html">SSH keys instructional</a> for details
        (just log in as <code>git</code> instead of <code>root</code>).
        </p>
        <h3>Syncing a new repository with your server</h3>
        <p>
        If you've just created a new repository on your local machine, you will
        need to tell <code>git</code> where the remote repository is to be able
        to sync with it (using commands like <code>git push</code> or
        <code>git pull</code>). We do this by defining a "remote" for your
        repository.
        </p>
        <p>
        A remote is just a named URL remembered in your repo's configuration. So
        we need a name and a URL. By convention, the "main" remote is called
        "origin". The URL has the format <code>user@host:path</code>, where:
        </p>
        <ul>
          <li>
            <code>user</code> is <code>git</code>, the <code>git</code> user
            we've already worked with before.
          </li>
          <li>
            <code>host</code> is your domain name.
            Alternatively you could even use your server's raw IP address.
          </li>
          <li>
            <code>path</code> is the absolute path to the repository on the
            server, in our example <code>/srv/git/my-repo.git</code>
          </li>
        </ul>
        </p>
        <p>
        So, to create a new remote, run:
        </p>
        <pre><code>git remote add origin git@yourdomain.xyz:/srv/git/my-repo.git</code></pre>
        <p>
        Now you'll be able to run <code>git push origin master</code> to push
        your commits or <code>git pull origin</code> to pull from the remote.
        </p>
        <h3>Syncing an existing repository</h3>
        <p>
        If you've already set up your local repository to sync with a service
        like GitHub it probably already has a remote called "origin". You can
        see your repo's remotes with:
        </p>
        <pre><code>git remote -v</code></pre>
        <p>
        You can follow the above instructions, substituting an arbitrary other
        name other than "origin" to create a differently named remote, e.g.
        </p>
        <pre><code>git remote add vps git@...</code></pre>
        <p>
        Now you'll be able to push/pull with <code>git push vps master</code>
        and <code>git pull vps</code>, respectively.
        </p>
        <p>
        Or, to completely sever ties with your centralized git provider, first
        remove the original origin with:
        <code>git remote remove origin</code>
        and then follow the instructions as above.
        </p>
        <h2>Contribution</h2>
        <ul>
            <li>Martin Chrzanowski -- <a href="https://m-chrzan.xyz">website</a>, <a href="https://m-chrzan.xyz/donate.html">donate</a></li>
        </ul>
    </main>

]]></description>
</item>


<item>
<title>Requiring Passwords for Webpages (HTTP Authentication)</title>
<guid>https://landchad.net/auth.html</guid>
<link>https://landchad.net/auth.html</link>
<pubDate>Thu, 01 Jul 2021 07:19:27 -0400</pubDate>
<description><![CDATA[
    <header><h1>Requiring Passwords for Webpages</h1></header>

    <main>
        <img class=titleimg src="pix/auth.svg" alt="access control with nginx"/>
        <p>HTTP basic authentication will allow you to secure parts (or all) of your website with a username and password without the trouble of PHP or Javascript.
        This will work with any Nginx server.
        </p>
        <h2>Installation</h2>
        <p>We will be using the command <code>htpasswd</code> to make username and password pairs.</p>
        <pre><code>apt install apache2-utils</code></pre>
        <aside>
            <p>The apache utils has a small username-password pair encryption tool.</p>
            <p>Like the other on this site, this tutorial is for Nginx, <strong>not</strong> for Apache servers.</p>
        </aside>
        <p>
        Now think of a username and password and remember them.
        </p>
        <pre><code>htpasswd -c /etc/nginx/<strong>myusers</strong> <strong>username</strong></code></pre>
        <aside>
            <p>The <code>-c</code> flag creates a file. You can make the path of this file anywhere outside of your webroot.</p>
            <p>Obviously the username is up to you as well.</p>
        </aside>
        <p>
        Type out your password twice to confirm. You can do this as many times as you'd like.
        </p>
        <p>Check out user name password pairs (the password will be securely hashed):</p>
        <pre><code>cat /etc/nginx/<strong>myusers</strong></code></pre>
        <h2>Nginx Config and Auth Basic</h2>
        <p>
        From here, we are going to edit our websites config file in <code>/etc/nginx/sites-enabled</code>.
        Have in mind which folder you'd like to secure. Add something like this:
        </p>
        <pre><code>server {
    #...
    location /<strong>secret-folder </strong> {
        auth_basic "What's the Password?" ;
        auth_basic_user_file /etc/nginx/<strong>myusers</strong> ;
    }
    #...
}</code></pre>
        <aside>
            <h4>Huh?</h4>
            <p>If you're stuck, try finding the line <code>location / {</code></p>
            <p>Just below this block is where you should add the custom location block</p>
        </aside>
        <p>If you'd like to do the opposite, such as making the entire site private except for a public section, do this:</p>
        <pre><code>server {
    #...
    auth_basic "What's the Password?" ;
    auth_basic_user_file /etc/nginx/<strong>myusers</strong> ;
    location /<strong>public</strong>/ {
        #...
        auth_basic off ;
    }
    #...
}</code></pre>
        <h3>IP Addresses</h3>
        <p>If passwords aren't enough we can ban an ip or accept one.</p>
        <pre><code>location /api {
    #...
    allow 192.168.1.23:8080 ;
    deny 127.0.0.1 ;
}</code></pre>
        <p>If you want to check both a username and password with an ip address, use the <code>satisfy</code> directive.</p>
        <pre><code>location /api {
    #...
    satify all ;
    allow 192.168.1.23:8080 ;
    deny 127.0.0.1 ;
    auth_basic "What's the Password?" ;
    auth_basic_user_file /etc/nginx/<strong>myusers</strong> ;
}</code></pre>
        <h3>Complete Example</h3>
        <pre><code>http {
    server {
        listen 80;
        root /var/www/website ;
        #...
        location /<strong>secret-folder</strong> {
            satisfy all ;
            allow 192.168.1.3/24;
            deny 127.0.0.1 ;
            auth_basic "What's the Password?" ;
            auth_basic_user_file /etc/nginx/<strong>myusers</strong> ;
        }
    }
}</code></pre>
        <p>
        Now check your configuration with <code>nginx -t</code>
        </p>
        <p>Reload nginx and you're good to go!</p>
        <strong>Contributor</strong>  -  <a href="https://tomfasano.xyz" target="_blank">tomfasano.xyz</a>
    </main>

]]></description>
</item>


<item>
<title>Cronjobs</title>
<guid>https://landchad.net/cron.html</guid>
<link>https://landchad.net/cron.html</link>
<pubDate>Thu, 01 Jul 2021 07:19:04 -0400</pubDate>
<description><![CDATA[
    <header><h1>Using Cronjobs to run scheduled tasks</h1></header>

    <main>
        <p>
        Cron is a service that lets you run scheduled tasks. These tasks are called <strong> cronjobs. </strong> If you have already followed the initial course you will have already used cron when you set up certbot.
        </p>
        <h2> What tasks would I want to schedule? </h2>
        <p>
        You can schedule anything! Some examples of what you might have done already include:
        <ul>
            <li> <code> updatedb </code> to update your <code> locate </code> database </li>
            <li> <code> certbot </code> to update renewing of your https certs </li>
        </ul>
        Some tasks that you might <em>want</em> to schedule may include:
        <ul>
            <li> Package updates - if you really just want to leave your server alone you can automated updating packages on your server </li>
            <li> Backups - you may want to backup certain files every day and some every week, this is possible with cron </li>
        </ul>
            <p>
            And many more, anything you can do can be turned into a cronjob.
            </p>
            <h2>Basic Cronjobs</h2>
            <p>
            This the preferred method for personal tasks and scripts, it's also the easiest to get started with. Run the command <code> crontab -e </code> to access your users crontab
            </p>
            <p>
            Once you have figured out the command you want to run you need to figure out how often you want to run it and when. I am going to schedule my system updates once a week on at 3:30 AM on a Monday.
            </p>
            <p>
            We now have to convert this time (Every Monday at 3:30 AM) into a cron time. Cron uses a simple but effective way of scheduling when to run things.
            </p>
            <p>
            Crontab expressions look like this <code> * * * * * command-to-run </code>
            The five elements before the command tell when the command is supposed to be run automatically.
            <p>
            So for our Monday at 3:30AM job we would do the following:
            <p>
            <pre><code> .---------------- minute (0 - 59)
 | .------------- hour (0 - 23)
 | | .---------- day of month (1 - 31)
 | | | .------- month (1 - 12
 | | | | .---- day of week (0 - 6)
 | | | | |
 * * * * *
30 3 * * 1 apt -y update && apt -y upgrade</code></pre>
            <h3>Some notes</h3>
            <ul>
                <li>On the day of the week option, Sunday is 0 and counting up from there, Saturday will be 6.</li>
                <li><code>*</code> designates "everything". Our command above has a <code>*</code> in the day of month and month columns. This means it will run regardless of the day of the month or month.</li>
                <li>The hour option uses 24 hour time. 3 = 3AM, while use 15 for 3PM.</li>
            </ul>
            <h3>More examples</h3>
            <p>
            Let's add another job, our backup job (for the purposes of this our backup command is just called <code> backup</code>) We want to run <code> backup </code> Every evening at 11PM, once we work out the timings for this we can add the to the same file as the above by running <code> crontab -e </code> This would mean our full crontab would look like this:
            <pre><code>0 23 * * * backup</code></pre>
            <h3>Consecutive times</h3>
            <p>
            Suppose we want a command to run every weekday.
            We know we can put <code>1</code> (Monday), but we can also use <code>1-5</code>
            to signify from day 1 (Monday) to day 5 (Friday).
            </p>
            <pre><code>0 6 * * 1-5 echo "Wakey, wakey, wagie!" >> /home/wagie/alarm</code></pre>
            <p>The above <code>echo</code> command runs every Monday through Friday at 6:00AM.</p>
            <h3>Non-consecutive times</h3>
            <p>
            We can also randomly specify non-consecutive arguments with a comma.
            Suppose you have a script you want to run at the midday of the 1st, 15th, and 20th day of every month.
            You can specify that my putting <code>1,15,20</code> for the day of the month argument:
            </p>
            <pre><code>0 12 1,15,20 * * /usr/bin/pay_bills_script</code></pre>
            <h3>"Every X minutes/days/months"</h3>
            <p>We can also easily run a command very several minutes or months, without specifying the specific times:
            </p>
            <pre><code>*/15 * * * * updatedb</code></pre>
            <p>
            This cronjob will run the <code>updatedb</code> command every 15 minutes.
            </p>
            <h3>Beware of this Rookie Mistake Though...</h3>
            <p>
            Suppose you want to run a script once every other month.
            You might be <em>tempted</em> write this:
            </p>
            <pre><code>* * * */2 *</code></pre>
            <p>
            That might <em>feel right</em>, but this script <em>will be running once every minute during that every other month</em>.
            You should specify the first two arguments, because with <code>*</code> it will be running every minute and hour!
            </p>
            <pre><code>0 0 1 */2 *</code></pre>
            <p>This makes the command run <em>only</em> at 0:00 (12:00AM) on the first day of every two months, which is what we really want.</p>
            <p>
            Consult the website <a href="https://crontab.guru">crontab.guru</a> for an intuitive and interactive tester of cronjobs.
            </p>
            <h2>User vs. Root Cronjobs</h2>
            <p>
            It is important to note that user accounts all have different cronjobs.
            If you have a user account <code>chad</code> and edit his crontab with <code>crontab -e</code>,
            the commands you add will be run as the <code>chad</code> user, not <code>root</code> or anyone else.
            </p>
            <p>
            Bear in mind that if you need root access to run a particular command,
            you will usually want to add it as root.
            </p>
            <h2>System-wide cron directories</h2>
            <p>
            <code>crontab -e</code> is the typical interface for adding cronjobs, but it's important to at least know that system-wide jobs are often stored in the file directory.
            Some programs which need cronjobs will automatically install them in the following way.
            </p>
            <p>
            Run the command <code> ls /etc/cron* </code> you should see a list of directories and there contents. The directories should be something like the below
            <ul>
                <li> /etc/cron.d  <em> This is a crontab like the ones that you create with </em> <code> crontab -e </code> </li>
                <li> /etc/cron.hourly </li>
                <li> /etc/cron.daily </li>
                <li> /etc/cron.weekly </li>
                <li> /etc/cron.monthly </li>
            </ul>
            <p>
            The directories cron.{hourly,daily,weekly,monthly} are where you can put <strong> scripts </strong> to run at those times. You don't put normal cron entries here. I prefer to use these directories for system wide jobs that don't relate to an individual user.
            </p>
            <h2>Contribution</h2>
            <ul>
                <li>Mark McNally -- <a href="https://mark.mcnally.je">website</a>, <a href="https://www.youtube.com/channel/UCMiInY8BhSUtCarO6uu6i_g">Youtube</a></li>
                <li>Edits and examples by Luke</li>
            </ul>
    </main>

]]></description>
</item>


<item>
<title>Mirror your site over tor</title>
<guid>https://landchad.net/tor.html</guid>
<link>https://landchad.net/tor.html</link>
<pubDate>Thu, 01 Jul 2021 07:15:39 -0400</pubDate>
<description><![CDATA[
    <header><h1>Mirror Your Site Over Tor</h1></header>

    <main>
        <img class=titleimg src="pix/tor.svg" alt="Tor logo">
        <p>
        Now that you have a website, why not offer it on a private alternative such as the onion network?
        </p>
        <h2>Setting up Tor</h2>
        <h3>Installing Tor</h3>
        <p>Firstly we need to add the tor repo's to have the latest up to date version or tor.</p>
        <pre><code>apt install -y apt-transport-https gpg
echo "deb https://deb.torproject.org/torproject.org buster main
deb-src https://deb.torproject.org/torproject.org buster main" > /etc/apt/sources.list.d/tor.list</code></pre>
	<p>Then we need to add the gpg keys to our keyring</p>
	<pre><code>curl -s https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --import
gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | apt-key add -</code></pre>
	<p>Now update and install tor</p>
	<pre><code>apt update
apt install tor deb.torproject.org-keyring</code></pre>
        <h3>Enabling Tor</h3>
        <p>Then edit the file <code>/etc/tor/torrc</code>, uncommenting the following lines:</p>
        <pre><code>HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80 127.0.0.1:80</code></pre>
        <aside>
            <h4>Optional: Running multiple onion services</h4>
            <p>If you want to forward multiple virtual ports for a single onion
            service, just add more HiddenServicePort lines (replace the 80 with any unoccupied port).
            </p>
            <p>If you want to run multiple onion services from the same Tor client, just add another
            HiddenServiceDir line.</p>
        </aside>
        <p>Now start and enable tor at boot</p>
        <pre><code> systemctl enable --now tor </code></pre>
        <p>If the next command outputs <q>active</q> in green you're golden!</p>
        <pre><code> systemctl status tor</code></pre>
        <p>Now you're server is on the dark web. The following command will give you your onion address:</p>
        <pre><code> cat /var/lib/tor/hidden_service/hostname</code></pre>
        <h2>Adding the Nginx Config</h2>
        <p>
        From here, the steps are almost identical to setting up a normal website configuration file.
        Follow the steps as if you were making a new website on the webserver
        <a href="nginx.html">tutorial</a> up until the server block of code. Instead, paste this:
        </p>
        <pre><code>        server {
            listen 127.0.0.1:80 ;
            root /var/www/<strong>landchad</strong> ;
            index index.html ;
            server_name <strong>your-onion-address</strong>.onion ;
        }</code></pre>
        <aside>
            <h4>Clarification</h4>
            <p>Nginx will listen on port 80 for your <em>server's</em> localhost.</p>
            <p>The <code>root</code> line is the path to whichever website of yours you'd like to mirror.</p>
        </aside>
        <p>
        From here we are almost done, all we have to do is enable the site and reload nginx which is also covered in <a href="nginx.html#enable">the webserver tutorial</a>.
        </p>
        <h3>Update regularly!</h3>
        <p>Make sure to update Tor on a regular basis by running:</p>
        <pre><code>apt update
apt install tor</code></pre>
        <p><strong>Contributor</strong>  -  <a href="https://tomfasano.xyz" target="_blank">tomfasano.xyz</a></p>
    </main>

]]></description>
</item>


<item>
	<title>Cryptocurrency Tutorials Completed</title>
	<guid>https://landchad.net/index.html#crypto</guid>
	<link>https://landchad.net/index.html#crypto</link>
	<pubDate> Tue, 29 Jun 2021 08:10:31 -0400</pubDate>
	<description><![CDATA[<p>There is now a set of basic tutorials on cryptocurrency wallets and concepts up.
		The goal here is to allow people to receive tips for sites using all free and open source and peer-to-peer technology.</p>

	<p>More tutorials on crypto management and exchanging may be added later, but these focus simply on basic concepts and setting up wallets. They include:</p>

	<ul>
		<li><a href="https://landchad.net/crypto.html">The Case for Crypto for Normal People</a></li>
		<li><a href="https://landchad.net/bitcoin.html">Accepting Bitcoin</a></li>
		<li><a href="https://landchad.net/monero.html">Accepting Monero</a></li>
		<li><a href="https://landchad.net/openalias.html">Setting up OpenAlias for your site</a></li>
		<li><a href="https://landchad.net/bat.html">Enrolling in the Basic Attention Token project</a></li>
	</ul>]]></description>
</item>

<item>
	<title>Welcome to LandChad.net!</title>
	<guid>https://landchad.net</guid>
	<link>https://landchad.net</link>
	<pubDate> Mon, 28 Jun 2021 08:21:44 -0400</pubDate>
	<description><![CDATA[<p>Welcome to LandChad.net!</p>
<p>This website is for step-by-step tutorials that allow people to host and maintain their own website and other web services on the cheap or free.</p>
<p>There is already a full basic tutorial on website creation on the site <a href="https://landchad.net/index.html#basic">here</a>.
Following the tutorials can take as little as an hour, but will help you set up a VPS, and NginX server and encrypt your new webpage with Certbot.</p>
<p>Next I plan adding general info on HTML and CSS and how to manage a website.</p>
<p>More stuff like running your own email server and more will be added shortly as more articles are finalized.</p>
]]></description>
</item>


</channel>
</rss>