mirror of
https://github.com/chillout2k/ldap-acl-milter.git
synced 2025-12-13 19:30:18 +00:00
commit
4a0bf680b8
@ -15,13 +15,6 @@ attributetype ( 1.3.6.1.4.1.53501.1.1.1
|
|||||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128}
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128}
|
||||||
SINGLE-VALUE)
|
SINGLE-VALUE)
|
||||||
|
|
||||||
attributetype ( 1.3.6.1.4.1.53501.1.1.2
|
|
||||||
NAME 'authType'
|
|
||||||
DESC 'Authentication type: sasl_user, client_addr, none'
|
|
||||||
EQUALITY caseExactIA5Match
|
|
||||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
|
|
||||||
SINGLE-VALUE)
|
|
||||||
|
|
||||||
attributetype ( 1.3.6.1.4.1.53501.1.1.3
|
attributetype ( 1.3.6.1.4.1.53501.1.1.3
|
||||||
NAME 'allowedSenders'
|
NAME 'allowedSenders'
|
||||||
DESC 'Allowed RFC5321.from'
|
DESC 'Allowed RFC5321.from'
|
||||||
@ -77,13 +70,29 @@ attributetype ( 1.3.6.1.4.1.53501.1.1.10
|
|||||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4096})
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4096})
|
||||||
|
|
||||||
|
attributetype ( 1.3.6.1.4.1.53501.1.1.11
|
||||||
|
NAME 'allowedx509subject'
|
||||||
|
DESC 'Allowed x509 Common Name - subject'
|
||||||
|
EQUALITY caseExactIA5Match
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64})
|
||||||
|
|
||||||
|
attributetype ( 1.3.6.1.4.1.53501.1.1.12
|
||||||
|
NAME 'allowedx509issuer'
|
||||||
|
DESC 'Allowed x509 Common Name - issuer'
|
||||||
|
EQUALITY caseExactIA5Match
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64})
|
||||||
|
|
||||||
#
|
#
|
||||||
# Objects: 1.3.6.1.4.1.53501.1.2
|
# Objects: 1.3.6.1.4.1.53501.1.2
|
||||||
#
|
#
|
||||||
objectclass ( 1.3.6.1.4.1.53501.1.2.1
|
objectclass ( 1.3.6.1.4.1.53501.1.2.1
|
||||||
NAME 'lamPolicy'
|
NAME 'lamPolicy'
|
||||||
DESC 'ldap-acl-milter policy'
|
DESC 'ldap-acl-milter policy'
|
||||||
SUP top
|
SUP top STRUCTURAL
|
||||||
STRUCTURAL
|
MUST policyID
|
||||||
MUST ( policyID $ allowedRcpts $ allowedSenders )
|
MAY ( allowedRcpts $ deniedRcpts $
|
||||||
MAY ( authType $ deniedSenders $ deniedRcpts $ allowedClientAddr $ deniedClientAddr $ allowedSaslUser $ extBLOB ))
|
allowedSenders $ deniedSenders $
|
||||||
|
allowedClientAddr $ deniedClientAddr $
|
||||||
|
allowedSaslUser $ extBLOB $
|
||||||
|
allowedx509subject $ allowedx509issuer )
|
||||||
|
)
|
||||||
|
|||||||
@ -76,6 +76,11 @@ services:
|
|||||||
#MILTER_SOCKET: inet6:8020
|
#MILTER_SOCKET: inet6:8020
|
||||||
#MILTER_REJECT_MESSAGE: Message rejected due to security policy
|
#MILTER_REJECT_MESSAGE: Message rejected due to security policy
|
||||||
#MILTER_TMPFAIL_MESSAGE: Message temporary rejected. Please try again later ;)
|
#MILTER_TMPFAIL_MESSAGE: Message temporary rejected. Please try again later ;)
|
||||||
|
# Expect authentication information from LDAP like allowedClientAddr,
|
||||||
|
# allowedSaslUser or allowedx509CN. This is usefull if the milter handles
|
||||||
|
# outbound email traffic, where senders must authenticate before submission.
|
||||||
|
# Default: False (inbound mode)
|
||||||
|
MILTER_EXPECT_AUTH: 'True'
|
||||||
hostname: ldap-acl-milter
|
hostname: ldap-acl-milter
|
||||||
volumes:
|
volumes:
|
||||||
- "lam_socket:/socket/:rw"
|
- "lam_socket:/socket/:rw"
|
||||||
|
|||||||
@ -29,6 +29,7 @@ g_milter_mode = 'test'
|
|||||||
g_milter_default_policy = 'reject'
|
g_milter_default_policy = 'reject'
|
||||||
g_milter_schema = False
|
g_milter_schema = False
|
||||||
g_milter_schema_wildcard_domain = False # works only if g_milter_schema == True
|
g_milter_schema_wildcard_domain = False # works only if g_milter_schema == True
|
||||||
|
g_milter_expect_auth = False
|
||||||
|
|
||||||
class LdapAclMilter(Milter.Base):
|
class LdapAclMilter(Milter.Base):
|
||||||
# Each new connection is handled in an own thread
|
# Each new connection is handled in an own thread
|
||||||
@ -39,7 +40,8 @@ class LdapAclMilter(Milter.Base):
|
|||||||
self.env_from = None
|
self.env_from = None
|
||||||
self.env_from_domain = None
|
self.env_from_domain = None
|
||||||
self.sasl_user = None
|
self.sasl_user = None
|
||||||
self.x509_cn = None
|
self.x509_subject = None
|
||||||
|
self.x509_issuer = None
|
||||||
# recipients list
|
# recipients list
|
||||||
self.env_rcpts = []
|
self.env_rcpts = []
|
||||||
# https://stackoverflow.com/a/2257449
|
# https://stackoverflow.com/a/2257449
|
||||||
@ -48,9 +50,9 @@ class LdapAclMilter(Milter.Base):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Not registered/used callbacks
|
# Not registered/used callbacks
|
||||||
@Milter.nocallback
|
#@Milter.nocallback
|
||||||
def hello(self, heloname):
|
#def hello(self, heloname)
|
||||||
return Milter.CONTINUE
|
# return Milter.CONTINUE
|
||||||
@Milter.nocallback
|
@Milter.nocallback
|
||||||
def header(self, name, hval):
|
def header(self, name, hval):
|
||||||
return Milter.CONTINUE
|
return Milter.CONTINUE
|
||||||
@ -70,13 +72,21 @@ class LdapAclMilter(Milter.Base):
|
|||||||
|
|
||||||
def envfrom(self, mailfrom, *str):
|
def envfrom(self, mailfrom, *str):
|
||||||
try:
|
try:
|
||||||
# this may fail, if no x509 client certificate was used
|
# this may fail, if no x509 client certificate was used.
|
||||||
x509cn = self.getsymval('{cert_subject}')
|
# postfix only passes this macro to milters if the TLS connection
|
||||||
if x509cn != None:
|
# with the authenticating client was trusted in a x509 manner!
|
||||||
self.x509_cn = x509cn
|
# http://postfix.1071664.n5.nabble.com/verification-levels-and-Milter-tp91634p91638.html
|
||||||
logging.info(self.mconn_id + "/FROM x509_cn=" + self.x509_cn)
|
# Unfortunately, postfix only passes the CN-field of the subject/issuer DN :-/
|
||||||
|
x509_subject = self.getsymval('{cert_subject}')
|
||||||
|
if x509_subject != None:
|
||||||
|
self.x509_subject = x509_subject
|
||||||
|
logging.info(self.mconn_id + "/FROM x509_subject=" + self.x509_subject)
|
||||||
|
x509_issuer = self.getsymval('{cert_issuer}')
|
||||||
|
if x509_issuer != None:
|
||||||
|
self.x509_issuer = x509_issuer
|
||||||
|
logging.info(self.mconn_id + "/FROM x509_issuer=" + self.x509_issuer)
|
||||||
except:
|
except:
|
||||||
logging.error(self.mconn_id + "/FROM " + traceback.format_exc())
|
logging.error(self.mconn_id + "/FROM x509 " + traceback.format_exc())
|
||||||
try:
|
try:
|
||||||
# this may fail, if no SASL authentication preceded
|
# this may fail, if no SASL authentication preceded
|
||||||
sasl_user = self.getsymval('{auth_authen}')
|
sasl_user = self.getsymval('{auth_authen}')
|
||||||
@ -84,7 +94,7 @@ class LdapAclMilter(Milter.Base):
|
|||||||
self.sasl_user = sasl_user
|
self.sasl_user = sasl_user
|
||||||
logging.info(self.mconn_id + "/FROM sasl_user=" + self.sasl_user)
|
logging.info(self.mconn_id + "/FROM sasl_user=" + self.sasl_user)
|
||||||
except:
|
except:
|
||||||
logging.error(self.mconn_id + "/FROM " + traceback.format_exc())
|
logging.error(self.mconn_id + "/FROM sasl_user " + traceback.format_exc())
|
||||||
mailfrom = mailfrom.replace("<","")
|
mailfrom = mailfrom.replace("<","")
|
||||||
mailfrom = mailfrom.replace(">","")
|
mailfrom = mailfrom.replace(">","")
|
||||||
self.env_from = mailfrom
|
self.env_from = mailfrom
|
||||||
@ -121,16 +131,26 @@ class LdapAclMilter(Milter.Base):
|
|||||||
if g_milter_schema == True:
|
if g_milter_schema == True:
|
||||||
# LDAP-ACL-Milter schema
|
# LDAP-ACL-Milter schema
|
||||||
auth_method = ''
|
auth_method = ''
|
||||||
# Authentication order!
|
if g_milter_expect_auth == True:
|
||||||
# 1. x509 client certificate
|
auth_method = "(|(allowedClientAddr="+self.client_addr+")%SASL_AUTH%%X509_AUTH%)"
|
||||||
# 2. SASL authenticated
|
if self.sasl_user:
|
||||||
# if authType sasl_user, check if authenticated user matches sasl_user and
|
auth_method = auth_method.replace(
|
||||||
# check if sender/recipient pair match
|
'%SASL_AUTH%',"(allowedSaslUser="+self.sasl_user+")"
|
||||||
# 3. Client-IP authenticated
|
)
|
||||||
# if authType client_addr, check if client-ip matches client_addr
|
else:
|
||||||
# check if sender/recipient pair match
|
auth_method = auth_method.replace('%SASL_AUTH%','')
|
||||||
# 4. not authenticated
|
if self.x509_subject and self.x509_issuer:
|
||||||
# ldap-search with excluded sasl_user and client_addr attributes!
|
auth_method = auth_method.replace('%X509_AUTH%',
|
||||||
|
"(&"+
|
||||||
|
"(allowedx509subject="+self.x509_subject+")"+
|
||||||
|
"(allowedx509issuer="+self.x509_issuer+")"+
|
||||||
|
")"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
auth_method = auth_method.replace('%X509_AUTH%','')
|
||||||
|
logging.debug(self.mconn_id +
|
||||||
|
" auth_method: " + auth_method
|
||||||
|
)
|
||||||
if g_milter_schema_wildcard_domain == True:
|
if g_milter_schema_wildcard_domain == True:
|
||||||
# The asterisk (*) character is in term of local part
|
# The asterisk (*) character is in term of local part
|
||||||
# RFC5322 compliant and expected as a wildcard literal in this code.
|
# RFC5322 compliant and expected as a wildcard literal in this code.
|
||||||
@ -139,16 +159,18 @@ class LdapAclMilter(Milter.Base):
|
|||||||
# for proper use in LDAP queries.
|
# for proper use in LDAP queries.
|
||||||
# In this case *@<domain> cannot be a real address!
|
# In this case *@<domain> cannot be a real address!
|
||||||
if re.match(r'^\*@.+$', self.env_from, re.IGNORECASE):
|
if re.match(r'^\*@.+$', self.env_from, re.IGNORECASE):
|
||||||
logging.info(self.mconn_id + "/RCPT REJECT "
|
logging.info(self.mconn_id + "/RCPT REJECT " +
|
||||||
+ "Wildcard sender (*@<domain>) is not allowed in wildcard mode!"
|
"Literal wildcard sender (*@<domain>) is not " +
|
||||||
|
"allowed in wildcard mode!"
|
||||||
)
|
)
|
||||||
self.setreply('550','5.7.1',
|
self.setreply('550','5.7.1',
|
||||||
g_milter_reject_message + ' (' + self.mconn_id + ')'
|
g_milter_reject_message + ' (' + self.mconn_id + ')'
|
||||||
)
|
)
|
||||||
return Milter.REJECT
|
return Milter.REJECT
|
||||||
if re.match(r'^\*@.+$', to, re.IGNORECASE):
|
if re.match(r'^\*@.+$', to, re.IGNORECASE):
|
||||||
logging.info(self.mconn_id + "/RCPT REJECT "
|
logging.info(self.mconn_id + "/RCPT REJECT " +
|
||||||
+ "Wildcard recipient (*@<domain>) is not allowed in wildcard mode!"
|
"Literal wildcard recipient (*@<domain>) is not " +
|
||||||
|
"allowed in wildcard mode!"
|
||||||
)
|
)
|
||||||
self.setreply('550','5.7.1',
|
self.setreply('550','5.7.1',
|
||||||
g_milter_reject_message + ' (' + self.mconn_id + ')'
|
g_milter_reject_message + ' (' + self.mconn_id + ')'
|
||||||
@ -160,12 +182,15 @@ class LdapAclMilter(Milter.Base):
|
|||||||
"(|"+
|
"(|"+
|
||||||
"(allowedRcpts="+to+")"+
|
"(allowedRcpts="+to+")"+
|
||||||
"(allowedRcpts=\\2a@"+rcpt_domain+")"+
|
"(allowedRcpts=\\2a@"+rcpt_domain+")"+
|
||||||
|
"(allowedRcpts=\\2a@\\2a)"+
|
||||||
")"+
|
")"+
|
||||||
"(|"+
|
"(|"+
|
||||||
"(allowedSenders="+self.env_from+")"+
|
"(allowedSenders="+self.env_from+")"+
|
||||||
"(allowedSenders=\\2a@"+self.env_from_domain+")"+
|
"(allowedSenders=\\2a@"+self.env_from_domain+")"+
|
||||||
")"+
|
"(allowedSenders=\\2a@\\2a)"+
|
||||||
")"
|
")"+
|
||||||
|
")",
|
||||||
|
attributes=['policyID']
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Asterisk must be ASCII-HEX encoded for LDAP queries
|
# Asterisk must be ASCII-HEX encoded for LDAP queries
|
||||||
@ -176,17 +201,25 @@ class LdapAclMilter(Milter.Base):
|
|||||||
auth_method +
|
auth_method +
|
||||||
"(allowedRcpts="+query_to+")" +
|
"(allowedRcpts="+query_to+")" +
|
||||||
"(allowedSenders="+query_from+")" +
|
"(allowedSenders="+query_from+")" +
|
||||||
")"
|
")",
|
||||||
|
attributes=['policyID']
|
||||||
)
|
)
|
||||||
time_end = timer()
|
time_end = timer()
|
||||||
if len(self.ldap_conn.entries) == 0:
|
if len(self.ldap_conn.entries) == 0:
|
||||||
|
# Policy not found in LDAP
|
||||||
self.env_rcpts.append({
|
self.env_rcpts.append({
|
||||||
"rcpt": to, "reason": g_milter_reject_message,
|
"rcpt": to, "action": g_milter_reject_message,
|
||||||
"time_start":time_start, "time_end":time_end
|
"time_start":time_start, "time_end":time_end
|
||||||
})
|
})
|
||||||
logging.info(self.mconn_id + "/RCPT " + "policy mismatch "
|
if g_milter_expect_auth == True:
|
||||||
"5321.from=" + self.env_from + ", 5321.rcpt=" + to
|
logging.info(self.mconn_id + "/RCPT " + "policy mismatch "
|
||||||
)
|
"5321.from=" + self.env_from + ", 5321.rcpt=" + to +
|
||||||
|
", auth_method=" + auth_method
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logging.info(self.mconn_id + "/RCPT " + "policy mismatch "
|
||||||
|
"5321.from=" + self.env_from + ", 5321.rcpt=" + to
|
||||||
|
)
|
||||||
if g_milter_mode == 'reject':
|
if g_milter_mode == 'reject':
|
||||||
logging.info(self.mconn_id + "/RCPT REJECT "
|
logging.info(self.mconn_id + "/RCPT REJECT "
|
||||||
+ g_milter_reject_message
|
+ g_milter_reject_message
|
||||||
@ -200,6 +233,22 @@ class LdapAclMilter(Milter.Base):
|
|||||||
g_milter_reject_message
|
g_milter_reject_message
|
||||||
)
|
)
|
||||||
return Milter.CONTINUE
|
return Milter.CONTINUE
|
||||||
|
elif len(self.ldap_conn.entries) == 1:
|
||||||
|
# Policy found in LDAP, but which one?
|
||||||
|
entry = self.ldap_conn.entries[0]
|
||||||
|
logging.info(self.mconn_id +
|
||||||
|
"/RCPT Policy match: " + entry.policyID.value
|
||||||
|
)
|
||||||
|
elif len(self.ldap_conn.entries) > 1:
|
||||||
|
# Something went wrong!? There shouldn´t be more than one entries!
|
||||||
|
logging.warn(self.mconn_id + "/RCPT More than one policies found! "+
|
||||||
|
"5321.from=" + self.env_from + ", 5321.rcpt=" + to +
|
||||||
|
", auth_method=" + auth_method
|
||||||
|
)
|
||||||
|
self.setreply('550','5.7.1',
|
||||||
|
g_milter_reject_message + ' (' + self.mconn_id + ')'
|
||||||
|
)
|
||||||
|
return Milter.REJECT
|
||||||
else:
|
else:
|
||||||
# Custom LDAP schema
|
# Custom LDAP schema
|
||||||
# 'build' a LDAP query per recipient
|
# 'build' a LDAP query per recipient
|
||||||
@ -215,7 +264,7 @@ class LdapAclMilter(Milter.Base):
|
|||||||
time_end = timer()
|
time_end = timer()
|
||||||
if len(self.ldap_conn.entries) == 0:
|
if len(self.ldap_conn.entries) == 0:
|
||||||
self.env_rcpts.append({
|
self.env_rcpts.append({
|
||||||
"rcpt": to, "reason": g_milter_reject_message,
|
"rcpt": to, "action": g_milter_reject_message,
|
||||||
"time_start":time_start, "time_end":time_end
|
"time_start":time_start, "time_end":time_end
|
||||||
})
|
})
|
||||||
logging.info(self.mconn_id + "/RCPT " + "policy mismatch "
|
logging.info(self.mconn_id + "/RCPT " + "policy mismatch "
|
||||||
@ -236,8 +285,12 @@ class LdapAclMilter(Milter.Base):
|
|||||||
logging.warn(self.mconn_id + "/RCPT LDAP: " + str(e))
|
logging.warn(self.mconn_id + "/RCPT LDAP: " + str(e))
|
||||||
self.setreply('451', '4.7.1', g_milter_tmpfail_message)
|
self.setreply('451', '4.7.1', g_milter_tmpfail_message)
|
||||||
return Milter.TEMPFAIL
|
return Milter.TEMPFAIL
|
||||||
|
except:
|
||||||
|
logging.error(self.mconn_id + "/RCPT LDAP: " + traceback.format_exc())
|
||||||
|
self.setreply('451', '4.7.1', g_milter_tmpfail_message)
|
||||||
|
return Milter.TEMPFAIL
|
||||||
self.env_rcpts.append({
|
self.env_rcpts.append({
|
||||||
"rcpt": to, "reason":'pass',"time_start":time_start,"time_end":time_end
|
"rcpt": to, "action":'pass',"time_start":time_start,"time_end":time_end
|
||||||
})
|
})
|
||||||
return Milter.CONTINUE
|
return Milter.CONTINUE
|
||||||
|
|
||||||
@ -250,7 +303,7 @@ class LdapAclMilter(Milter.Base):
|
|||||||
duration = rcpt['time_end'] - rcpt['time_start']
|
duration = rcpt['time_end'] - rcpt['time_start']
|
||||||
logging.info(self.mconn_id + "/DATA " + self.queue_id +
|
logging.info(self.mconn_id + "/DATA " + self.queue_id +
|
||||||
": 5321.from=" + self.env_from + " 5321.rcpt=" +
|
": 5321.from=" + self.env_from + " 5321.rcpt=" +
|
||||||
rcpt['rcpt'] + " reason=" + rcpt['reason'] +
|
rcpt['rcpt'] + " action=" + rcpt['action'] +
|
||||||
" duration=" + str(duration) + "sec."
|
" duration=" + str(duration) + "sec."
|
||||||
)
|
)
|
||||||
except:
|
except:
|
||||||
@ -338,6 +391,9 @@ if __name__ == "__main__":
|
|||||||
g_milter_reject_message = os.environ['MILTER_REJECT_MESSAGE']
|
g_milter_reject_message = os.environ['MILTER_REJECT_MESSAGE']
|
||||||
if 'MILTER_TMPFAIL_MESSAGE' in os.environ:
|
if 'MILTER_TMPFAIL_MESSAGE' in os.environ:
|
||||||
g_milter_tmpfail_message = os.environ['MILTER_TMPFAIL_MESSAGE']
|
g_milter_tmpfail_message = os.environ['MILTER_TMPFAIL_MESSAGE']
|
||||||
|
if 'MILTER_EXPECT_AUTH' in os.environ:
|
||||||
|
if re.match(r'^true$', os.environ['MILTER_EXPECT_AUTH'], re.IGNORECASE):
|
||||||
|
g_milter_expect_auth = True
|
||||||
server = Server(g_ldap_server, get_info=NONE)
|
server = Server(g_ldap_server, get_info=NONE)
|
||||||
g_ldap_conn = Connection(server,
|
g_ldap_conn = Connection(server,
|
||||||
g_ldap_binddn, g_ldap_bindpw,
|
g_ldap_binddn, g_ldap_bindpw,
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
BRANCH="$(/usr/bin/git branch|/bin/grep \*|/usr/bin/awk {'print $2'})"
|
BRANCH="$(/usr/bin/git branch|/bin/grep \*|/usr/bin/awk {'print $2'})"
|
||||||
VERSION="$(/bin/cat VERSION)"
|
VERSION="$(/bin/cat VERSION)"
|
||||||
BASEOS="$(/bin/cat BASEOS)"
|
BASEOS="$(/bin/cat BASEOS)"
|
||||||
#REGISTRY="some-registry.invalid"
|
|
||||||
GO=""
|
GO=""
|
||||||
|
|
||||||
while getopts g opt
|
while getopts g opt
|
||||||
@ -22,15 +21,7 @@ fi
|
|||||||
IMAGES="ldap-acl-milter"
|
IMAGES="ldap-acl-milter"
|
||||||
|
|
||||||
for IMAGE in ${IMAGES}; do
|
for IMAGE in ${IMAGES}; do
|
||||||
# --build-arg http_proxy=http://wprx-zdf.zwackl.local:3128 \
|
|
||||||
# --build-arg https_proxy=http://wprx-zdf.zwackl.local:3128 \
|
|
||||||
/usr/bin/docker build \
|
/usr/bin/docker build \
|
||||||
-t "${IMAGE}/${BASEOS}:${VERSION}_${BRANCH}" \
|
-t "${IMAGE}:${BRANCH}" \
|
||||||
-f "docker/${BASEOS}/Dockerfile" .
|
-f "docker/${BASEOS}/Dockerfile" .
|
||||||
# /usr/bin/docker tag "${IMAGE}/${BASEOS}:${VERSION}_${BRANCH}" "${REGISTRY}/${IMAGE}/${BASEOS}:${VERSION}_${BRANCH}"
|
|
||||||
done
|
done
|
||||||
|
|
||||||
#/bin/echo "Push images to registry:"
|
|
||||||
#for IMAGE in ${IMAGES}; do
|
|
||||||
# /bin/echo "/usr/bin/docker push ${REGISTRY}/${IMAGE}/${BASEOS}:${VERSION}_${BRANCH}"
|
|
||||||
#done
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ ARG http_proxy
|
|||||||
ARG https_proxy
|
ARG https_proxy
|
||||||
FROM debian
|
FROM debian
|
||||||
LABEL maintainer="Dominik Chilla <dominik@zwackl.de>"
|
LABEL maintainer="Dominik Chilla <dominik@zwackl.de>"
|
||||||
LABEL git_repo="https://github.com/chillout2k/ldap-acl-milter/tree/devel"
|
LABEL git_repo="https://github.com/chillout2k/ldap-acl-milter"
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive \
|
ENV DEBIAN_FRONTEND=noninteractive \
|
||||||
TZ=Europe/Berlin
|
TZ=Europe/Berlin
|
||||||
@ -18,7 +18,8 @@ RUN env; set -ex ; \
|
|||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY app/*.py /app/
|
ADD app/*.py /app/
|
||||||
COPY entrypoint.sh /entrypoint.sh
|
ADD entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
ENTRYPOINT ["/entrypoint.sh"]
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
|
CMD ["/usr/bin/python3", "/app/ldap-acl-milter.py"]
|
||||||
|
|||||||
@ -4,4 +4,4 @@ set -x
|
|||||||
set -e
|
set -e
|
||||||
umask 0000
|
umask 0000
|
||||||
ulimit -n 1024
|
ulimit -n 1024
|
||||||
/usr/bin/python3 /app/ldap-acl-milter.py
|
exec "$@"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user