Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

   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
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">

<head>

<title>Postfix Postscreen Howto (Postfix 2.8 - 3.5)</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

</head>

<body>

<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Postscreen Howto (Postfix 2.8 - 3.5)</h1>

<hr>

<h2> <a name="intro">Introduction</a> </h2>

<p> This document describes features that are available in Postfix
2.8 - 3.5. </p>

<p> The Postfix <a href="postscreen.8.html">postscreen(8)</a> daemon provides additional protection
against mail server overload. One <a href="postscreen.8.html">postscreen(8)</a> process handles
multiple inbound SMTP connections, and decides which clients may
talk to a Postfix SMTP server process.  By keeping spambots away,
<a href="postscreen.8.html">postscreen(8)</a> leaves more SMTP server processes available for
legitimate clients, and delays the onset of <a
href="STRESS_README.html">server overload</a> conditions. </p>

<p> <a href="postscreen.8.html">postscreen(8)</a> should not be used on SMTP ports that receive
mail from end-user clients (MUAs). In a typical deployment,
<a href="postscreen.8.html">postscreen(8)</a> handles the MX service on TCP port 25, while MUA
clients submit mail via the submission service on TCP port 587 which
requires client authentication. Alternatively, a site could set up
a dedicated, non-postscreen, "port 25" server that provides submission
service and client authentication, but no MX service.  </p>

<p> <a href="postscreen.8.html">postscreen(8)</a> maintains a temporary allowlist for clients that
pass its tests; by allowing allowlisted clients to skip tests,
<a href="postscreen.8.html">postscreen(8)</a> minimizes its impact on legitimate email traffic.
</p>

<p> <a href="postscreen.8.html">postscreen(8)</a> is part of a multi-layer defense. <p>

<ul>

<li> <p> As the first layer, <a href="postscreen.8.html">postscreen(8)</a> blocks connections from
zombies and other spambots that are responsible for about 90% of
all spam.  It is implemented as a single process to make this defense
as inexpensive as possible. </p>

<li> <p> The second layer implements more complex SMTP-level access
checks with <a href="SMTPD_ACCESS_README.html">Postfix SMTP servers</a>, 
<a href="SMTPD_POLICY_README.html">policy daemons</a>, and 
<a href="MILTER_README.html">Milter applications</a>. </p>

<li> <p> The third layer performs light-weight content inspection
with the Postfix built-in <a href="postconf.5.html#header_checks">header_checks</a> and <a href="postconf.5.html#body_checks">body_checks</a>. This can
block unacceptable attachments such as executable programs, and
worms or viruses with easy-to-recognize signatures. </p>

<li> <p> The fourth layer provides heavy-weight content inspection
with external content filters. Typical examples are <a
href="http://www.ijs.si/software/amavisd/">Amavisd-new</a>, <a
href="http://spamassassin.apache.org/">SpamAssassin</a>, and <a
href="MILTER_README.html">Milter applications</a>. </p>

</ul>

<p> Each layer reduces the spam volume. The general strategy is to
use the less expensive defenses first, and to use the more expensive
defenses only for the spam that remains. </p>

<p> Topics in this document: </p>

<ul>

<li> <a href="#intro">Introduction</a>

<li> <a href="#basic">The basic idea behind postscreen(8)</a>

<li> <a href="#general"> General operation </a>

<li> <a href="#quick">Quick tests before everything else</a>

<li> <a href="#before_220"> Tests before the 220 SMTP server greeting </a>

<li> <a href="#after_220">Tests after the 220 SMTP server greeting</a>

<li> <a href="#other_error">Other errors</a>

<li> <a href="#victory">When all tests succeed</a>

<li> <a href="#config"> Configuring the postscreen(8) service</a>

<li> <a href="#historical"> Historical notes and credits </a>

</ul>

<h2> <a name="basic">The basic idea behind postscreen(8)</a> </h2>

<p> Most email is spam, and most spam is sent out by zombies (malware
on compromised end-user computers).  Wietse expects that the zombie
problem will get worse before things improve, if ever. Without a
tool like <a href="postscreen.8.html">postscreen(8)</a> that keeps the zombies away, Postfix would be
spending most of its resources not receiving email. </p>

<p> The main challenge for <a href="postscreen.8.html">postscreen(8)</a> is to make an is-a-zombie
decision based on a single measurement. This is necessary because
many zombies try to fly under the radar and avoid spamming the same
site repeatedly.  Once <a href="postscreen.8.html">postscreen(8)</a> decides that a client is
not-a-zombie, it allowlists the client temporarily to avoid further
delays for legitimate mail. </p>

<p> Zombies have challenges too: they have only a limited amount
of time to deliver spam before their IP address becomes denylisted.
To speed up spam deliveries, zombies make compromises in their SMTP
protocol implementation.  For example, they speak before their turn,
or they ignore responses from SMTP servers and continue sending
mail even when the server tells them to go away. </p>

<p> <a href="postscreen.8.html">postscreen(8)</a> uses a variety of measurements to recognize
zombies.  First, <a href="postscreen.8.html">postscreen(8)</a> determines if the remote SMTP client
IP address is denylisted.  Second, <a href="postscreen.8.html">postscreen(8)</a> looks for protocol
compromises that are made to speed up delivery.  These are good
indicators for making is-a-zombie decisions based on single
measurements.  </p>

<p> <a href="postscreen.8.html">postscreen(8)</a> does not inspect message content. Message content
can vary from one delivery to the next, especially with clients
that (also) send legitimate email.  Content is not a good indicator
for making is-a-zombie decisions based on single measurements,
and that is the problem that <a href="postscreen.8.html">postscreen(8)</a> is focused on.  </p>

<h2> <a name="general"> General operation </a> </h2>

<p> For each connection from an SMTP client, <a href="postscreen.8.html">postscreen(8)</a> performs
a number of tests
in the order as described below.  Some tests introduce a delay of
a few seconds.  <a href="postscreen.8.html">postscreen(8)</a> maintains a temporary allowlist for
clients that pass its tests; by allowing allowlisted clients to
skip tests, <a href="postscreen.8.html">postscreen(8)</a> minimizes its impact on legitimate email
traffic.  </p>

<p> By default, <a href="postscreen.8.html">postscreen(8)</a> hands off all connections to a Postfix
SMTP server process after logging its findings. This mode is useful
for non-destructive testing. </p>

<p> In a typical production setting, <a href="postscreen.8.html">postscreen(8)</a> is configured
to reject mail from clients that fail one or more tests, after
logging the helo, sender and recipient information. </p>

<p> Note: <a href="postscreen.8.html">postscreen(8)</a> is not an SMTP proxy; this is intentional.
The purpose is to keep zombies away from Postfix, with minimal
overhead for legitimate clients. </p>

<h2> <a name="quick">Quick tests before everything else</a> </h2>

<p> Before engaging in SMTP-level tests. <a href="postscreen.8.html">postscreen(8)</a> queries a
number of local deny and allowlists. These tests speed up the
handling of known clients. </p>

<ul>

<li> <a href="#perm_white_black"> Permanent allow/denylist test </a>

<li> <a href="#temp_white"> Temporary allowlist test </a>

<li> <a href="#white_veto"> MX Policy test </a>

</ul>

<h3> <a name="perm_white_black"> Permanent allow/denylist test </a> </h3>

<p> The <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> parameter (default: <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>)
specifies a permanent access list for SMTP client IP addresses. Typically
one would specify something that allowlists local networks, followed
by a CIDR table for selective allow- and denylisting. </p>

<p> Example: </p>

<pre>
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
    <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> = <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>,
        <a href="cidr_table.5.html">cidr</a>:/etc/postfix/postscreen_access.cidr

/etc/postfix/postscreen_access.<a href="cidr_table.5.html">cidr</a>:
   # Rules are evaluated in the order as specified.
   # Denylist 192.168.* except 192.168.0.1.
   192.168.0.1          permit
   192.168.0.0/16       reject
</pre>

<p> See the <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> manpage documentation for more
details.  </p>

<p> When the SMTP client address matches a "permit" action,
<a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port number as:
</p>

<pre>
    <b>WHITELISTED</b> <i>[address]:port</i>
</pre>

<p> The allowlist action is not configurable: immediately hand off the
connection to a Postfix SMTP server process. </p>

<p> When the SMTP client address matches a "reject" action,
<a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port number as:
</p>

<pre>
    <b>BLACKLISTED</b> <i>[address]:port</i>
</pre>

<p> The <a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> parameter specifies the action
that is taken next.  See "<a href="#fail_before_220">When tests
fail before the 220 SMTP server greeting</a>" below. </p>

<h3> <a name="temp_white"> Temporary allowlist test </a> </h3>

<p> The <a href="postscreen.8.html">postscreen(8)</a> daemon maintains a <i>temporary</i>
allowlist for SMTP client IP addresses that have passed all
the tests described below. The <a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> parameter
specifies the location of the temporary allowlist.  The
temporary allowlist is not used for SMTP client addresses
that appear on the <i>permanent</i> access list. </p>

<p> By default the temporary allowlist is not shared with other
<a href="postscreen.8.html">postscreen(8)</a> daemons. See
<a href="#temp_white_sharing"> Sharing
the temporary allowlist </a> below for alternatives. </p>

<p> When the SMTP client address appears on the temporary
allowlist, <a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port
number as: </p>

<pre>
    <b>PASS OLD</b> <i>[address]:port</i>
</pre>

<p> The action is not configurable: immediately hand off the
connection to a Postfix SMTP server process.  The client is
excluded from further tests until its temporary allowlist
entry expires, as controlled with the postscreen_*_ttl
parameters.  Expired entries are silently renewed if possible. </p>

<h3> <a name="white_veto"> MX Policy test </a> </h3>

<p> When the remote SMTP client is not on the static access list
or temporary allowlist, <a href="postscreen.8.html">postscreen(8)</a> can implement a number of
allowlist tests, before it grants the client a temporary allowlist
status that allows it to talk to a Postfix SMTP server process. </p>

<p> When <a href="postscreen.8.html">postscreen(8)</a> is configured to monitor all primary and
backup MX addresses, it can refuse to allowlist clients that connect
to a backup MX address only (an old spammer trick to take advantage
of backup MX hosts with weaker anti-spam policies than primary MX
hosts). </p>

<blockquote> <p> NOTE: The following solution is for small sites.
Larger sites would have to share the <a href="postscreen.8.html">postscreen(8)</a> cache between
primary and backup MTAs, which would introduce a common point of
failure.  </p> </blockquote>

<ul>

<li> <p> First, configure the host to listen on both primary and
backup MX addresses. Use the appropriate <tt>ifconfig</tt> or <tt>ip</tt>
command for the local operating system, or update the appropriate
configuration files and "refresh" the network protocol stack. </p>

<p> <p> Second, configure Postfix to listen on the new IP address
(this step is needed when you have specified <a href="postconf.5.html#inet_interfaces">inet_interfaces</a> in
<a href="postconf.5.html">main.cf</a>). </p>

<li> <p> Then, configure <a href="postscreen.8.html">postscreen(8)</a> to deny the temporary allowlist
status on the backup MX address(es).  An example for Wietse's
server is: </p>

<pre>
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
    <a href="postconf.5.html#postscreen_whitelist_interfaces">postscreen_whitelist_interfaces</a> = !168.100.189.8 <a href="DATABASE_README.html#types">static</a>:all
</pre>

<p> Translation: allow clients to obtain the temporary allowlist
status on all server IP addresses except 168.100.189.8, which is a
backup MX address.  </p>

</ul>

<p> When a non-allowlisted client connects the backup MX address,
<a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port number as:
</p>

<pre>
    <b>CONNECT from</b> <i>[address]:port</i> <b>to [168.100.189.8]:25</b>
    <b>WHITELIST VETO</b> <i>[address]:port</i>
</pre>

<p> Translation: the client at <i>[address]:port</i> connected to
the backup MX address 168.100.189.8 while it was not allowlisted.
The client will not be granted the temporary allowlist status, even
if passes all the allowlist tests described below. </p>

<h2> <a name="before_220"> Tests before the 220 SMTP server greeting </a> </h2>

<p> The <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> parameter specifies a short time
interval before the "220 <i>text</i>..." server greeting, where
<a href="postscreen.8.html">postscreen(8)</a> can run a number of tests in parallel. </p>

<p> When a good client passes these tests, and no "<a
href="#after_220">deep protocol tests</a>"
are configured, <a href="postscreen.8.html">postscreen(8)</a>
adds the client to the temporary allowlist and hands off the "live"
connection to a Postfix SMTP server process.  The client can then
continue as if <a href="postscreen.8.html">postscreen(8)</a> never even existed (except of course
for the short <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> delay).  </p>

<ul>

<li> <a href="#pregreet"> Pregreet test </a>

<li> <a href="#dnsbl"> DNS Allow/denylist test </a>

<li> <a href="#fail_before_220">When tests fail before the 220 SMTP server greeting</a>

</ul>

<h3> <a name="pregreet"> Pregreet test </a> </h3>

<p> The SMTP protocol is a classic example of a protocol where the
server speaks before the client. <a href="postscreen.8.html">postscreen(8)</a> detects zombies
that are in a hurry and that speak before their turn. This test is
enabled by default. </p>

<p> The <a href="postconf.5.html#postscreen_greet_banner">postscreen_greet_banner</a> parameter specifies the <i>text</i>
portion of a "220-<i>text</i>..." teaser banner (default: $<a href="postconf.5.html#smtpd_banner">smtpd_banner</a>).
Note that this becomes the first part of a multi-line server greeting.
The <a href="postscreen.8.html">postscreen(8)</a> daemon sends this before the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a>
timer is started.  The purpose of the teaser banner is to confuse
zombies so that they speak before their turn. It has no effect on
SMTP clients that correctly implement the protocol.  </p>

<p> To avoid problems with poorly-implemented SMTP engines in network
appliances or network testing tools, either exclude them from all
tests with the <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> feature or else specify
an empty teaser banner: </p>

<pre>
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
    # Exclude broken clients by allowlisting. Clients in <a href="postconf.5.html#mynetworks">mynetworks</a>
    # should always be allowlisted.
    <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> = <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>, 
        <a href="cidr_table.5.html">cidr</a>:/etc/postfix/postscreen_access.cidr

/etc/postfix/postscreen_access.<a href="cidr_table.5.html">cidr</a>:
    192.168.254.0/24 permit
</pre>

<pre>
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
    # Disable the teaser banner (try allowlisting first if you can).
    <a href="postconf.5.html#postscreen_greet_banner">postscreen_greet_banner</a> =
</pre>

<p> When an SMTP client sends a command before the
<a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> time has elapsed, <a href="postscreen.8.html">postscreen(8)</a> logs this as:
</p>

<pre>
    <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>[address]:port text...</i>
</pre>

<p> Translation: the client at <i>[address]:port</i> sent <i>count</i>
bytes before its turn to speak. This happened <i>time</i> seconds
after the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> timer was started.  The <i>text</i>
is what the client sent (truncated to 100 bytes, and with non-printable
characters replaced with C-style escapes such as \r for carriage-return
and \n for newline). </p>

<p> The <a href="postconf.5.html#postscreen_greet_action">postscreen_greet_action</a> parameter specifies the action that
is taken next.  See "<a href="#fail_before_220">When tests fail
before the 220 SMTP server greeting</a>" below. </p>

<h3> <a name="dnsbl"> DNS Allow/denylist test </a> </h3>

<p> The <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> parameter (default: empty) specifies
a list of DNS blocklist servers with optional filters and weight
factors (positive weights for denylisting, negative for allowlisting).
These servers will be queried in parallel with the reverse client
IP address.  This test is disabled by default. </p>

<blockquote>
<p>
CAUTION: when postscreen rejects mail, its SMTP reply contains the
DNSBL domain name. Use the <a href="postconf.5.html#postscreen_dnsbl_reply_map">postscreen_dnsbl_reply_map</a> feature to
hide "password" information in DNSBL domain names.
</p>
</blockquote>

<p> When the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> time has elapsed, and the combined
DNSBL score is equal to or greater than the <a href="postconf.5.html#postscreen_dnsbl_threshold">postscreen_dnsbl_threshold</a>
parameter value, <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p>

<pre>
    <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>[address]:port</i>
</pre>

<p> Translation: the SMTP client at <i>[address]:port</i> has a combined
DNSBL score of <i>count</i>. </p>

<p> The <a href="postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action</a> parameter specifies the action that
is taken when the combined DNSBL score is equal to or greater than
the threshold.  See "<a href="#fail_before_220">When tests fail
before the 220 SMTP server greeting</a>" below. </p>

<h3> <a name="fail_before_220">When tests fail before the 220 SMTP server greeting</a> </h3>

<p> When the client address matches the permanent denylist, or
when the client fails the pregreet or DNSBL tests, the action is
specified with <a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a>, <a href="postconf.5.html#postscreen_greet_action">postscreen_greet_action</a>,
or <a href="postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action</a>, respectively. </p>

<dl>

<dt> <b>ignore</b> (default) </dt>

<dd> Ignore the failure of this test. Allow other tests to complete.
Repeat this test the next time the client connects.  This option
is useful for testing and collecting statistics without blocking
mail. </dd>

<dt> <b>enforce</b> </dt>

<dd> Allow other tests to complete.  Reject attempts to deliver mail
with a 550 SMTP reply, and log the helo/sender/recipient information.
Repeat this test the next time the client connects. </dd>

<dt> <b>drop</b> </dt>

<dd> Drop the connection immediately with a 521 SMTP reply.  Repeat
this test the next time the client connects. </dd>

</dl>

<h2> <a name="after_220">Tests after the 220 SMTP server greeting</a> </h2>

<p> In this phase of the protocol, <a href="postscreen.8.html">postscreen(8)</a> implements a
number of "deep protocol" tests. These tests use an SMTP protocol
engine that is built into the <a href="postscreen.8.html">postscreen(8)</a> server. </p>

<p> Important note: these protocol tests are disabled by default.
They are more intrusive than the pregreet and DNSBL tests, and they
have limitations as discussed next. </p>

<ul>

<li> <p> The main limitation of "after 220 greeting" tests is that
a new client must disconnect after passing these tests (reason:
postscreen is not a proxy).  Then the client must reconnect from
the same IP address before it can deliver mail.  The following
measures may help to avoid email delays: </p>

<ul>

<li> <p> Allow "good" clients to skip tests with the
<a href="postconf.5.html#postscreen_dnsbl_whitelist_threshold">postscreen_dnsbl_whitelist_threshold</a> feature (Postfix 2.11 and
later). This is especially effective for sites such as Google that
never retry immediately from the same IP address. </p>

<li> <p> Small sites: Configure <a href="postscreen.8.html">postscreen(8)</a> to listen on multiple
IP addresses, published in DNS as different IP addresses for the
same MX hostname or for different MX hostnames. This avoids mail
delivery delays with clients that reconnect immediately from the
same IP address.  </p>

<li> <p> Large sites: Share the <a href="postscreen.8.html">postscreen(8)</a> cache between different
Postfix MTAs with a large-enough <a href="memcache_table.5.html">memcache_table(5)</a>. Again, this
avoids mail delivery delays with clients that reconnect immediately
from the same IP address. </p>

</ul>

<li> <p> <a href="postscreen.8.html">postscreen(8)</a>'s built-in SMTP engine does not implement the
AUTH, XCLIENT, and XFORWARD features. If you need to make these
services available on port 25, then do not enable the tests after
the 220 server greeting. </p>

<li> <p> End-user clients should connect directly to the submission
service, so that they never have to deal with <a href="postscreen.8.html">postscreen(8)</a>'s tests.
</p>

</ul>

<p> The following "after 220 greeting" tests are available: </p>

<ul>

<li> <a href="#pipelining">Command pipelining test</a>

<li> <a href="#non_smtp">Non-SMTP command test</a>

<li> <a href="#barelf">Bare newline test</a>

<li> <a href="#fail_after_220">When tests fail after the 220 SMTP server greeting</a>

</ul>

<h3> <a name="pipelining">Command pipelining test</a> </h3>

<p> By default, SMTP is a half-duplex protocol: the sender and
receiver send one command and one response at a time.  Unlike the
Postfix SMTP server, <a href="postscreen.8.html">postscreen(8)</a> does not announce support
for ESMTP command pipelining.  Therefore, clients are not allowed
to send multiple commands. <a href="postscreen.8.html">postscreen(8)</a>'s
<a href="#after_220">deep
protocol test</a> for this is disabled by default. </p>

<p> With "<a href="postconf.5.html#postscreen_pipelining_enable">postscreen_pipelining_enable</a> = yes", <a href="postscreen.8.html">postscreen(8)</a> detects
zombies that send multiple commands, instead of sending one command
and waiting for the server to reply.  </p>

<p> This test is opportunistically enabled when <a href="postscreen.8.html">postscreen(8)</a> has
to use the built-in SMTP engine anyway. This is to make <a href="postscreen.8.html">postscreen(8)</a>
logging more informative. </p>

<p> When a client sends multiple commands, <a href="postscreen.8.html">postscreen(8)</a> logs this
as: </p>

<pre>
    <b>COMMAND PIPELINING from</b> <i>[address]:port</i> <b>after</b> <i>command</i>: <i>text</i>
</pre>

<p> Translation: the SMTP client at <i>[address]:port</i> sent
multiple SMTP commands, instead of sending one command and then
waiting for the server to reply. This happened after the client
sent <i>command</i>. The <i>text</i> shows part of the input that
was sent too early; it is not logged with Postfix 2.8. </p>

<p> The <a href="postconf.5.html#postscreen_pipelining_action">postscreen_pipelining_action</a> parameter specifies the action
that is taken next.  See "<a href="#fail_after_220">When tests fail
after the 220 SMTP server greeting</a>" below. </p>

<h3> <a name="non_smtp">Non-SMTP command test</a> </h3>

<p> Some spambots send their mail through open proxies. A symptom
of this is the usage of commands such as CONNECT and other non-SMTP
commands. Just like the Postfix SMTP server's <a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a>
feature, <a href="postscreen.8.html">postscreen(8)</a> has an equivalent <a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a>
feature to block these clients. <a href="postscreen.8.html">postscreen(8)</a>'s
<a href="#after_220">deep
protocol test</a> for this is disabled by default.  </p>

<p> With "<a href="postconf.5.html#postscreen_non_smtp_command_enable">postscreen_non_smtp_command_enable</a> = yes", <a href="postscreen.8.html">postscreen(8)</a>
detects zombies that send commands specified with the
<a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a> parameter. This also detects commands
with the syntax of a message header label. The latter is a symptom
that the client is sending message content after ignoring all the
responses from <a href="postscreen.8.html">postscreen(8)</a> that reject mail. </p>

<p> This test is opportunistically enabled when <a href="postscreen.8.html">postscreen(8)</a> has
to use the built-in SMTP engine anyway. This is to make <a href="postscreen.8.html">postscreen(8)</a>
logging more informative.  </p>

<p> When a client sends non-SMTP commands, <a href="postscreen.8.html">postscreen(8)</a> logs this
as: </p>

<pre>
    <b>NON-SMTP COMMAND from</b> <i>[address]:port</i> <b>after</b> <i>command: text</i>
</pre>

<p> Translation: the SMTP client at <i>[address]:port</i> sent a
command that matches the <a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a>
parameter, or that has the syntax of a message header label (text 
followed by optional space and ":").
The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
Postfix 2.10 and later. </p>

<p> The <a href="postconf.5.html#postscreen_non_smtp_command_action">postscreen_non_smtp_command_action</a> parameter specifies
the action that is taken next.  See "<a href="#fail_after_220">When
tests fail after the 220 SMTP server greeting</a>" below. </p>

<h3> <a name="barelf">Bare newline test</a> </h3>

<p> SMTP is a line-oriented protocol: lines have a limited length,
and are terminated with &lt;CR&gt;&lt;LF&gt;. Lines ending in a
"bare" &lt;LF&gt;, that is newline not preceded by carriage return,
are not allowed in SMTP.  <a href="postscreen.8.html">postscreen(8)</a>'s
<a href="#after_220">deep
protocol test</a> for this is disabled by default.  </p>

<p> With "<a href="postconf.5.html#postscreen_bare_newline_enable">postscreen_bare_newline_enable</a> = yes", <a href="postscreen.8.html">postscreen(8)</a>
detects clients that send lines ending in bare newline characters.
</p>

<p> This test is opportunistically enabled when <a href="postscreen.8.html">postscreen(8)</a> has
to use the built-in SMTP engine anyway. This is to make <a href="postscreen.8.html">postscreen(8)</a>
logging more informative.  </p>

<p> When a client sends bare newline characters, <a href="postscreen.8.html">postscreen(8)</a> logs
this as:
</p>

<pre>
    <b>BARE NEWLINE from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
</pre>

<p> Translation: the SMTP client at <i>[address]:port</i> sent a bare
newline character, that is newline not preceded by carriage
return.
The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
Postfix 2.10 and later. </p>

<p> The <a href="postconf.5.html#postscreen_bare_newline_action">postscreen_bare_newline_action</a> parameter specifies the
action that is taken next.  See "<a href="#fail_after_220">When
tests fail after the 220 SMTP server greeting</a>" below. </p>

<h3> <a name="fail_after_220">When tests fail after the 220 SMTP server greeting</a> </h3>

<p> When the client fails the pipelining, non-SMTP command or bare
newline tests, the action is specified with <a href="postconf.5.html#postscreen_pipelining_action">postscreen_pipelining_action</a>,
<a href="postconf.5.html#postscreen_non_smtp_command_action">postscreen_non_smtp_command_action</a> or <a href="postconf.5.html#postscreen_bare_newline_action">postscreen_bare_newline_action</a>,
respectively. </p>

<dl>

<dt> <b>ignore</b> (default for bare newline) </dt>

<dd> Ignore the failure of this test. Allow other tests to complete.
Do NOT repeat this test before the result from some other test
expires.

This option is useful for testing and collecting statistics without
blocking mail permanently. </dd>

<dt> <b>enforce</b> (default for pipelining) </dt>

<dd> Allow other tests to complete.  Reject attempts to deliver
mail with a 550 SMTP reply, and log the helo/sender/recipient
information.  Repeat this test the next time the client connects.
</dd>

<dt> <b>drop</b> (default for non-SMTP commands) </dt>

<dd> Drop the connection immediately with a 521 SMTP reply.  Repeat
this test the next time the client connects.  This action is
compatible with the Postfix SMTP server's <a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a>
feature. </dd>

</dl>

<h2> <a name="other_error">Other errors</a> </h2>

<p> When an SMTP client hangs up unexpectedly, <a href="postscreen.8.html">postscreen(8)</a> logs
this as: </p>

<pre>
    <b>HANGUP after</b> <i>time</i> <b>from</b> <i>[address]:port</i> <b>in</b> <i>test name</i>
</pre>

<p> Translation: the SMTP client at <i>[address]:port</i> disconnected
unexpectedly, <i>time</i> seconds after the start of the
test named <i>test name</i>. </p>

<p> There is no punishment for hanging up. A client that hangs up
without sending the QUIT command can still pass all <a href="postscreen.8.html">postscreen(8)</a>
tests. </p>

<!--

<p> While an unexpired penalty is in effect, an SMTP client is not
allowed to pass any tests, and  <a href="postscreen.8.html">postscreen(8)</a> logs each connection
with the remaining amount of penalty time as: </p>

<pre>
    <b>PENALTY</b> <i>time</i> <b>for</b> <i>[address]:port</i>
</pre>

<p> During this time, all attempts by the client to deliver mail
will be deferred with a 450 SMTP status.  </p>

-->

<p> The following errors are reported by the built-in SMTP engine.
This engine never accepts mail, therefore it has per-session limits
on the number of commands and on the session length. </p>

<pre>
    <b>COMMAND TIME LIMIT</b> <b>from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
</pre>

<p> Translation: the SMTP client at <i>[address]:port</i> reached the
per-command time limit as specified with the <a href="postconf.5.html#postscreen_command_time_limit">postscreen_command_time_limit</a>
parameter.  The session is terminated immediately.
The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
Postfix 2.10 and later. </p>

<pre>
    <b>COMMAND COUNT LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
</pre>

<p> Translation: the SMTP client at <i>[address]:port</i> reached the
per-session command count limit as specified with the
<a href="postconf.5.html#postscreen_command_count_limit">postscreen_command_count_limit</a> parameter.  The session is terminated
immediately.
The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
Postfix 2.10 and later. </p>

<pre>
    <b>COMMAND LENGTH LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
</pre>

<p> Translation: the SMTP client at <i>[address]:port</i> reached the
per-command length limit, as specified with the <a href="postconf.5.html#line_length_limit">line_length_limit</a>
parameter.  The session is terminated immediately.
The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
Postfix 2.10 and later. </p>

<p> When an SMTP client makes too many connections at the same time,
<a href="postscreen.8.html">postscreen(8)</a> rejects the connection with a 421 status code and logs: </p>

<pre>
    <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: too many connections</b>
</pre>

<p> The <a href="postconf.5.html#postscreen_client_connection_count_limit">postscreen_client_connection_count_limit</a> parameter controls this limit. </p>

<p> When an SMTP client connects after <a href="postscreen.8.html">postscreen(8)</a> has reached a
connection count limit, <a href="postscreen.8.html">postscreen(8)</a> rejects the connection with
a 421 status code and logs: </p>

<pre>
    <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all screening ports busy</b>
    <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all server ports busy</b>
</pre>

<p> The <a href="postconf.5.html#postscreen_pre_queue_limit">postscreen_pre_queue_limit</a> and <a href="postconf.5.html#postscreen_post_queue_limit">postscreen_post_queue_limit</a>
parameters control these limits.  </p>

<h2> <a name="victory">When all tests succeed</a> </h2>

<p> When a new SMTP client passes all tests (i.e. it is not allowlisted
via some mechanism), <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p>

<pre>
    <b>PASS NEW</b> <i>[address]:port</i>
</pre>

<p> Where <i>[address]:port</i> are the client IP address and port.
Then, <a href="postscreen.8.html">postscreen(8)</a>
creates a temporary allowlist entry that excludes the client IP
address from further tests until the temporary allowlist entry
expires, as controlled with the postscreen_*_ttl parameters. </p>

<p> When no "<a href="#after_220">deep protocol tests</a>" are
configured, <a href="postscreen.8.html">postscreen(8)</a> hands off the "live" connection to a Postfix
SMTP server process.  The client can then continue as if <a href="postscreen.8.html">postscreen(8)</a>
never even existed (except for the short <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> delay).
</p>

<p> When any "<a href="#after_220">deep protocol tests</a>" are
configured, <a href="postscreen.8.html">postscreen(8)</a> cannot hand off the "live" connection to
a Postfix SMTP server process in the middle of the session.  Instead,
<a href="postscreen.8.html">postscreen(8)</a> defers mail delivery attempts with a 4XX status, logs
the helo/sender/recipient information, and waits for the client to
disconnect.  The next time the client connects it will be allowed
to talk to a Postfix SMTP server process to deliver its mail.
<a href="postscreen.8.html">postscreen(8)</a> mitigates the impact of this limitation by giving
<a href="#after_220">deep protocol tests</a> a long expiration
time. </p>

<h2> <a name="config"> Configuring the postscreen(8) service</a>
</h2>

<p> <a href="postscreen.8.html">postscreen(8)</a> has been tested on FreeBSD [4-8], Linux 2.[4-6]
and Solaris 9 systems. </p>

<ul>

<li> <a href="#enable"> Turning on postscreen(8) without blocking
mail</a>

<li> <a href="#starttls"> postscreen(8) TLS configuration </a>

<li> <a href="#blocking"> Blocking mail with postscreen(8) </a>

<li> <a href="#turnoff"> Turning off postscreen(8) </a>

<li> <a href="#temp_white_sharing"> Sharing the temporary allowlist
</a>

</ul>

<h3> <a name="enable"> Turning on postscreen(8) without blocking mail</a> </h3>

<p> To enable the <a href="postscreen.8.html">postscreen(8)</a> service and log client information
without blocking mail: </p>

<ol>

<li> <p> Make sure that local clients and systems with non-standard
SMTP implementations are excluded from any <a href="postscreen.8.html">postscreen(8)</a> tests. The
default is to exclude all clients in <a href="postconf.5.html#mynetworks">mynetworks</a>. To exclude additional
clients, for example, third-party performance monitoring tools (these
tend to have broken SMTP implementations): </p>

<pre>
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
    # Exclude broken clients by allowlisting. Clients in <a href="postconf.5.html#mynetworks">mynetworks</a>
    # should always be allowlisted.
    <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> = <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>, 
        <a href="cidr_table.5.html">cidr</a>:/etc/postfix/postscreen_access.cidr

/etc/postfix/postscreen_access.<a href="cidr_table.5.html">cidr</a>:
    192.168.254.0/24 permit
</pre>

<li> <p> Comment out the "<tt>smtp  inet ... smtpd</tt>" service
in <a href="master.5.html">master.cf</a>, including any "<tt>-o parameter=value</tt>" entries
that follow.  </p>

<pre>
/etc/postfix/<a href="master.5.html">master.cf</a>:
    #smtp      inet  n       -       n       -       -       smtpd
    #    -o parameter=value ...
</pre>

<li> <p> Uncomment the new "<tt>smtpd pass ... smtpd</tt>" service
in <a href="master.5.html">master.cf</a>, and duplicate any "<tt>-o parameter=value</tt>" entries
from the smtpd service that was commented out in the previous step.
</p>

<pre>
/etc/postfix/<a href="master.5.html">master.cf</a>:
    smtpd     pass  -       -       n       -       -       smtpd
        -o parameter=value ...
</pre>

<li> <p> Uncomment the new "<tt>smtp inet ... postscreen</tt>"
service in <a href="master.5.html">master.cf</a>. </p>

<pre>
/etc/postfix/<a href="master.5.html">master.cf</a>:
    smtp      inet  n       -       n       -       1       postscreen
</pre>

<li> <p> Uncomment the new "<tt>tlsproxy unix ... tlsproxy</tt>"
service in <a href="master.5.html">master.cf</a>.  This service implements STARTTLS support for
<a href="postscreen.8.html">postscreen(8)</a>. </p>

<pre>
/etc/postfix/<a href="master.5.html">master.cf</a>:
    tlsproxy  unix  -       -       n       -       0       tlsproxy
</pre>

<li> <p> Uncomment the new "<tt>dnsblog  unix ... dnsblog</tt>"
service in <a href="master.5.html">master.cf</a>.  This service does DNSBL lookups for <a href="postscreen.8.html">postscreen(8)</a>
and logs results. </p>

<pre>
/etc/postfix/<a href="master.5.html">master.cf</a>:
    dnsblog   unix  -       -       n       -       0       dnsblog
</pre>

<li> <p> To enable DNSBL lookups, list some DNS blocklist sites in
<a href="postconf.5.html">main.cf</a>, separated by whitespace. Different sites can have different
weights. For example:

<pre>
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
    <a href="postconf.5.html#postscreen_dnsbl_threshold">postscreen_dnsbl_threshold</a> = 2
    <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> = zen.spamhaus.org*2 
        bl.spamcop.net*1 b.barracudacentral.org*1
</pre>

<p> Note: if your DNSBL queries have a "secret" in the domain name,
you must censor this information from the <a href="postscreen.8.html">postscreen(8)</a> SMTP replies.
For example: </p>

<pre>
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
    <a href="postconf.5.html#postscreen_dnsbl_reply_map">postscreen_dnsbl_reply_map</a> = <a href="DATABASE_README.html#types">texthash</a>:/etc/postfix/dnsbl_reply
</pre>

<pre>
/etc/postfix/dnsbl_reply:
    # Secret DNSBL name           Name in <a href="postscreen.8.html">postscreen(8)</a> replies
    secret.zen.dq.spamhaus.net    zen.spamhaus.org
</pre>

<p> The <a href="DATABASE_README.html#types">texthash</a>: format is similar to <a href="DATABASE_README.html#types">hash</a>: except that there is
no need to run <a href="postmap.1.html">postmap(1)</a> before the file can be used, and that it
does not detect changes after the file is read. It is new with
Postfix version 2.8. </p>

<li> <p> Read the new configuration with "<tt>postfix reload</tt>".
</p>

</ol>

<p> Notes: </p>

<ul>

<li> <p> Some <a href="postscreen.8.html">postscreen(8)</a> configuration parameters implement
stress-dependent behavior. This is supported only when the default
value is stress-dependent (that is, "postconf -d <i>parametername</i>"
output shows
"<i>parametername</i>&nbsp;=&nbsp;${stress?<i>something</i>}${stress:<i>something</i>}" or
"<i>parametername</i>&nbsp;=&nbsp;${stress?{<i>something</i>}:{<i>something</i>}}").
Other parameters always evaluate as if the stress value is the empty
string. </p>

<li> <p> See "<a href="#before_220">Tests before the 220 SMTP server
greeting</a>" for details about the logging from these
<a href="postscreen.8.html">postscreen(8)</a> tests. </p>

<li> <p> If you run Postfix 2.6 or earlier you must stop and start
the master daemon ("<tt>postfix stop; postfix start</tt>").  This
is needed because the Postfix "pass" master service type did not
work reliably on all systems. </p>

</ul>

<h3> <a name="starttls"> postscreen(8) TLS configuration </a> </h3>

<p> <a href="postscreen.8.html">postscreen(8)</a> TLS support is available for remote SMTP clients
that aren't allowlisted, including clients that need to renew their
temporary allowlist status.  When a remote SMTP client requests TLS
service, <a href="postscreen.8.html">postscreen(8)</a> invisibly hands off the connection to a
<a href="tlsproxy.8.html">tlsproxy(8)</a> process. Then, <a href="tlsproxy.8.html">tlsproxy(8)</a> encrypts and decrypts the
traffic between <a href="postscreen.8.html">postscreen(8)</a> and the remote SMTP client. One
<a href="tlsproxy.8.html">tlsproxy(8)</a> process can handle multiple SMTP sessions. The number
of <a href="tlsproxy.8.html">tlsproxy(8)</a> processes slowly increases with server load, but it
should always be much smaller than the number of <a href="postscreen.8.html">postscreen(8)</a> TLS
sessions.  </p>

<p> TLS support for <a href="postscreen.8.html">postscreen(8)</a> and <a href="tlsproxy.8.html">tlsproxy(8)</a> uses the same
parameters as with <a href="smtpd.8.html">smtpd(8)</a>. We recommend that you keep the relevant
configuration parameters in <a href="postconf.5.html">main.cf</a>.  If you must specify "-o
smtpd_mumble=value" parameter overrides in <a href="master.5.html">master.cf</a> for a
postscreen-protected <a href="smtpd.8.html">smtpd(8)</a> service, then you should specify those
same parameter overrides for the <a href="postscreen.8.html">postscreen(8)</a> and <a href="tlsproxy.8.html">tlsproxy(8)</a>
services. </p>

<h3> <a name="blocking"> Blocking mail with postscreen(8) </a> </h3>

<p> For compatibility with <a href="smtpd.8.html">smtpd(8)</a>, <a href="postscreen.8.html">postscreen(8)</a> implements the
<a href="postconf.5.html#soft_bounce">soft_bounce</a> safety feature. This causes Postfix to reject mail with
a "try again" reply code. </p>

<ul> 

<li> <p> To turn this on for all of Postfix, specify "<tt><a href="postconf.5.html#soft_bounce">soft_bounce</a>
= yes</tt>" in <a href="postconf.5.html">main.cf</a>. </p>

<li> <p> To turn this on for <a href="postscreen.8.html">postscreen(8)</a> only, append "<tt>-o
<a href="postconf.5.html#soft_bounce">soft_bounce</a>=yes</tt>" (note: NO SPACES around '=') to the postscreen
entry in <a href="master.5.html">master.cf</a>. <p>

</ul>

<p> Execute "<tt>postfix reload</tt>" to make the change effective. </p>

<p> After testing, do not forget to remove the <a href="postconf.5.html#soft_bounce">soft_bounce</a> feature,
otherwise senders won't receive their non-delivery notification
until many days later.  </p>

<p> To use the <a href="postscreen.8.html">postscreen(8)</a> service to block mail, edit <a href="postconf.5.html">main.cf</a> and
specify one or more of: </p>

<ul>

<li> <p> "<tt><a href="postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action</a> = enforce</tt>", to reject
clients that are on DNS blocklists, and to log the helo/sender/recipient
information. With good DNSBLs this reduces the amount of load on
Postfix SMTP servers dramatically.  </p>

<li> <p> "<tt><a href="postconf.5.html#postscreen_greet_action">postscreen_greet_action</a> = enforce</tt>", to reject
clients that talk before their turn, and to log the helo/sender/recipient
information. This stops over half of all known-to-be illegitimate
connections to Wietse's mail server. It is backup protection for
zombies that haven't yet been denylisted. </p>

<li> <p> You can also enable "<a href="#after_220">deep protocol
tests</a>", but these are more intrusive than the pregreet or DNSBL
tests. </p>

<p> When a good client passes the "<a href="#after_220">deep
protocol tests</a>",
<a href="postscreen.8.html">postscreen(8)</a> adds the client to the temporary
allowlist but it cannot hand off the "live" connection to a Postfix
SMTP server process in the middle of the session. Instead, <a href="postscreen.8.html">postscreen(8)</a>
defers mail delivery attempts with a 4XX status, logs the
helo/sender/recipient information, and waits for the client to
disconnect. </p>

<p> When the good client comes back in a later session, it is allowed
to talk directly to a Postfix SMTP server.  See "<a href="#after_220">Tests
after the 220 SMTP server greeting</a>" above for limitations with
AUTH and other features that clients may need.  </p>

<p> An unexpected benefit from "<a href="#after_220">deep protocol
tests</a>" is that some "good" clients don't return after the 4XX
reply; these clients were not so good after all. </p>

<p> Unfortunately, some senders will retry requests from different
IP addresses, and may never get allowlisted.  For this reason,
Wietse stopped using "<a href="#after_220">deep protocol tests</a>"
on his own internet-facing mail server.  </p>

<li> <p> There is also support for permanent denylisting and
allowlisting; see the description of the <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a>
parameter for details. </p>

</ul>

<h3> <a name="turnoff"> Turning off postscreen(8) </a> </h3>

<p> To turn off <a href="postscreen.8.html">postscreen(8)</a> and handle mail directly with Postfix
SMTP server processes: </p>

<ol>

<li> <p> Comment out the "<tt>smtp inet ... postscreen</tt>" service
in <a href="master.5.html">master.cf</a>, including any "<tt>-o parameter=value</tt>" entries
that follow. </p>

<pre>
/etc/postfix/<a href="master.5.html">master.cf</a>:
    #smtp      inet  n       -       n       -       1       postscreen
    #    -o parameter=value ...
</pre>

<li> <p> Comment out the "<tt>dnsblog  unix ... dnsblog</tt>" service
in <a href="master.5.html">master.cf</a>.  </p>

<pre>
/etc/postfix/<a href="master.5.html">master.cf</a>:
    #dnsblog   unix  -       -       n       -       0       dnsblog
</pre>

<li> <p> Comment out the "<tt>smtpd pass ... smtpd</tt>" service
in <a href="master.5.html">master.cf</a>, including any "<tt>-o parameter=value</tt>" entries
that follow. </p>

<pre>
/etc/postfix/<a href="master.5.html">master.cf</a>:
    #smtpd     pass  -       -       n       -       -       smtpd
    #    -o parameter=value ...
</pre>

<li> <p> Comment out the "<tt>tlsproxy unix ... tlsproxy</tt>"
service in <a href="master.5.html">master.cf</a>, including any "<tt>-o parameter=value</tt>"
entries that follow. </p>

<pre>
/etc/postfix/<a href="master.5.html">master.cf</a>:
    #tlsproxy  unix  -       -       n       -       0       tlsproxy
    #    -o parameter=value ...
</pre>

<li> <p> Uncomment the "<tt>smtp  inet ... smtpd</tt>" service in
<a href="master.5.html">master.cf</a>, including any "<tt>-o parameter=value</tt>" entries that
may follow.  </p>

<pre>
/etc/postfix/<a href="master.5.html">master.cf</a>:
    smtp       inet  n       -       n       -       -       smtpd
        -o parameter=value ...
</pre>

<li> <p> Read the new configuration with "<tt>postfix reload</tt>".
</p>

</ol>

<h3> <a name="temp_white_sharing"> Sharing the temporary allowlist </a> </h3>

<p> By default, the temporary allowlist is not shared between
multiple <a href="postscreen.8.html">postscreen(8)</a> daemons.  To enable sharing, choose one
of the following options: </p>

<ul>

<li> <p> A non-persistent <a href="memcache_table.5.html">memcache</a>: temporary allowlist can be shared
    between <a href="postscreen.8.html">postscreen(8)</a> daemons on the same host or different
    hosts.  Disable cache cleanup (<a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a>
    = 0) in all <a href="postscreen.8.html">postscreen(8)</a> daemons because <a href="memcache_table.5.html">memcache</a>: has no
    first-next API (but see example 4 below for <a href="memcache_table.5.html">memcache</a>: with
    persistent backup). This requires Postfix 2.9 or later. </p>

    <pre>
    # Example 1: non-persistent <a href="memcache_table.5.html">memcache</a>: allowlist.
    /etc/postfix/<a href="postconf.5.html">main.cf</a>:
        <a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> = <a href="memcache_table.5.html">memcache</a>:/etc/postfix/postscreen_cache
        <a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> = 0

    /etc/postfix/postscreen_cache:
        memcache = inet:127.0.0.1:11211
        key_format = postscreen:%s
    </pre>

<li> <p>
    A persistent <a href="lmdb_table.5.html">lmdb</a>: temporary allowlist can be shared between
    <a href="postscreen.8.html">postscreen(8)</a> daemons that run under the same <a href="master.8.html">master(8)</a> daemon,
    or under different <a href="master.8.html">master(8)</a> daemons on the same host.  Disable
    cache cleanup (<a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> = 0) in all
    <a href="postscreen.8.html">postscreen(8)</a> daemons except one that is responsible for cache
    cleanup. This requires Postfix 2.11 or later. </p>

    <pre>
    # Example 2: persistent <a href="lmdb_table.5.html">lmdb</a>: allowlist.
    /etc/postfix/<a href="postconf.5.html">main.cf</a>:
        <a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> = <a href="lmdb_table.5.html">lmdb</a>:$<a href="postconf.5.html#data_directory">data_directory</a>/postscreen_cache
        # See note 1 below.
        # <a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> = 0
    </pre>

<li> <p> Other kinds of persistent temporary allowlist can be shared
    only between <a href="postscreen.8.html">postscreen(8)</a> daemons that run under the same
    <a href="master.8.html">master(8)</a> daemon. In this case, temporary allowlist access must
    be shared through the <a href="proxymap.8.html">proxymap(8)</a> daemon. This requires Postfix
    2.9 or later. </p>

    <pre> 
    # Example 3: proxied <a href="DATABASE_README.html#types">btree</a>: allowlist.
    /etc/postfix/<a href="postconf.5.html">main.cf</a>:
        <a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> = 
            <a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/postscreen_cache
        # See note 1 below.
        # <a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> = 0

    # Example 4: proxied <a href="DATABASE_README.html#types">btree</a>: allowlist with <a href="memcache_table.5.html">memcache</a>: accelerator.
    /etc/postfix/<a href="postconf.5.html">main.cf</a>:
        <a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> = <a href="memcache_table.5.html">memcache</a>:/etc/postfix/postscreen_cache
        <a href="postconf.5.html#proxy_write_maps">proxy_write_maps</a> = 
            <a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/postscreen_cache 
            ... other proxied tables ...
        # See note 1 below.
        # <a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> = 0

    /etc/postfix/postscreen_cache:
        # Note: the $<a href="postconf.5.html#data_directory">data_directory</a> macro is not defined in this context.
        memcache = inet:127.0.0.1:11211
        backup = <a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/postscreen_cache
        key_format = postscreen:%s
    </pre>

    <p> Note 1: disable cache cleanup (<a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a>
    = 0) in all <a href="postscreen.8.html">postscreen(8)</a> daemons except one that is responsible
    for cache cleanup. </p>

    <p> Note 2: <a href="postscreen.8.html">postscreen(8)</a> cache sharing via <a href="proxymap.8.html">proxymap(8)</a> requires Postfix
    2.9 or later; earlier <a href="proxymap.8.html">proxymap(8)</a> implementations don't support
    cache cleanup.  </p>

</ul>

<h2> <a name="historical"> Historical notes and credits </a> </h2>

<p> Many ideas in <a href="postscreen.8.html">postscreen(8)</a> were explored in earlier work by
Michael Tokarev, in OpenBSD spamd, and in MailChannels Traffic
Control. </p>

<p> Wietse threw together a crude prototype with pregreet and dnsbl
support in June 2009, because he needed something new for a Mailserver
conference presentation in July. Ralf Hildebrandt ran this code on
several servers to collect real-world statistics. This version used
the <a href="dnsblog.8.html">dnsblog(8)</a> ad-hoc DNS client program. </p>

<p> Wietse needed new material for a LISA conference presentation
in November 2010, so he added support for DNSBL weights and filters
in August, followed by a major code rewrite, deep protocol tests,
helo/sender/recipient logging, and stress-adaptive behavior in
September. Ralf Hildebrandt ran this code on several servers to
collect real-world statistics. This version still used the embarrassing
<a href="dnsblog.8.html">dnsblog(8)</a> ad-hoc DNS client program.  </p>

<p> Wietse added STARTTLS support in December 2010. This makes
<a href="postscreen.8.html">postscreen(8)</a> usable for sites that require TLS support.  The
implementation introduces the <a href="tlsproxy.8.html">tlsproxy(8)</a> event-driven TLS proxy
that decrypts/encrypts the sessions for multiple SMTP clients. </p>

<p> The <a href="tlsproxy.8.html">tlsproxy(8)</a> implementation led to the discovery of a "new"
class of vulnerability (<a
href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-0411"
>CVE-2011-0411</a>) that affected multiple implementations of SMTP,
POP, IMAP, NNTP, and FTP over TLS. </p>

<p> <a href="postscreen.8.html">postscreen(8)</a> was officially released as part of the Postfix
2.8 stable release in January 2011.</p>

</body>

</html>