diff --git a/modules/modules.mk b/modules/modules.mk
index 2a55751098e64ac3876bddd8bef862c26106745a..d6077ebc713c2496163c71970cb0f35c4e651cb0 100644
--- a/modules/modules.mk
+++ b/modules/modules.mk
@@ -26,7 +26,8 @@ modules_TARGETS += ketcd \
                    dns64 \
                    renumber \
                    http \
-                   daf
+                   daf \
+                   version
 endif
 
 # Make C module
diff --git a/modules/version/README.rst b/modules/version/README.rst
new file mode 100644
index 0000000000000000000000000000000000000000..47a740de93780fb8991b4c69f3c6f1892148cd2c
--- /dev/null
+++ b/modules/version/README.rst
@@ -0,0 +1,15 @@
+.. _mod-version:
+
+Version
+-------
+
+Module checks for new version and CVEs_.
+
+Running
+^^^^^^^
+
+.. code-block:: lua
+
+	   modules.load("version")
+
+.. _cves: https://cve.mitre.org/
diff --git a/modules/version/version.lua b/modules/version/version.lua
new file mode 100644
index 0000000000000000000000000000000000000000..6d3a9c3cb43e5a35d72b45bf3eaa8527df5a3c0c
--- /dev/null
+++ b/modules/version/version.lua
@@ -0,0 +1,86 @@
+local M = {}
+
+local function getLastWord(str)
+    local space = 1
+    for i=#str, 1, -1 do
+        if str:sub(i,i) == " " then
+            space = i
+            break
+        end
+    end
+    return str:sub(space+1, #str)
+end
+
+--Converts string of HEX digits to string
+local function hex2string(hex)
+    local str = ""
+    for i=1, #hex, 2 do
+        local ascii = tonumber(hex:sub(i,i+1), 16)
+        str = str .. string.char(ascii)
+    end
+    return str
+end
+
+--Runs "kresd -V" to get installed version
+local function getLocalVersion()
+    local file = io.popen("kresd -V")
+    local version = file:read('*all')
+    file:close()
+    version = getLastWord(version):sub(1,-2)
+    return version
+end
+
+local function parseCVE(str)
+    local first
+    local last
+    first, last = str:find("CVE")
+    local position = last+2
+    return str:sub(position,-1)
+end
+    
+local function parseVersion(str)
+    local branch = "stable"
+    local first
+    local last
+    first, last = str:find(branch)
+    local position = last+3
+    local delimiter = #str
+    if str:find("|",position) then
+        delimiter = str:find("|",position)-1
+    end
+    return str:sub(position, delimiter)
+end
+
+--Parses version from server and compares it to the installed one
+local function parse(record)
+    local output = ""
+    local str = getLastWord(kres.rr2str(record))
+    str = hex2string(str)
+    local CVE = parseCVE(str)
+    local version = parseVersion(str)
+    local localVersion = getLocalVersion()
+    if version ~= localVersion then
+        output = output .. string.format("[version] Newer version of Knot DNS Resolver is available. (Current: %s, Available: %s)\n", localVersion, version)
+    end
+    if CVE ~= "N/A" then
+        output = output .. string.format("[version] CVE: %s\n", CVE)
+    end
+    io.write(output)
+end
+
+--Parses record from answer
+local function request (answer)
+    local pkt = kres.pkt_t(answer)
+    if pkt:rcode() == kres.rcode.NOERROR then
+        parse(pkt:section(kres.section.ANSWER)[1])
+    else
+        print ('Request for version ended with rcode: ', pkt:rcode())
+        return
+    end
+end
+
+function M.init()
+    resolve('et.knot-resolver.cz', kres.type.TXT, kres.class.IN, 0, request)
+end
+
+return M
\ No newline at end of file
diff --git a/modules/version/version.mk b/modules/version/version.mk
new file mode 100644
index 0000000000000000000000000000000000000000..34b261fe6dd3d12544c186b46f273b22157d9ccc
--- /dev/null
+++ b/modules/version/version.mk
@@ -0,0 +1,2 @@
+version_SOURCES := version.lua
+$(call make_lua_module,version)