-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit da7cd15
Showing
7 changed files
with
372 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
name: Build Docker Image | ||
|
||
on: | ||
push: | ||
branches-ignore: | ||
- '**' | ||
tags: | ||
- 'v*' | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: Generate docker image metadata | ||
uses: docker/metadata-action@v5 | ||
id: metadata | ||
with: | ||
images: "ghcr.io/${{ github.actor }}/dns-mx-watchdog" | ||
tags: | | ||
type=semver,pattern={{version}} | ||
type=semver,pattern={{major}}.{{minor}} | ||
- name: Login to GitHub Container Registry | ||
uses: docker/login-action@v3 | ||
with: | ||
registry: ghcr.io | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Build and push docker image | ||
uses: docker/build-push-action@v5 | ||
with: | ||
context: . | ||
push: true | ||
tags: ${{ steps.metadata.outputs.tags }} | ||
labels: ${{ steps.metadata.outputs.labels }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
# Created by https://www.toptal.com/developers/gitignore/api/go,goland,dotenv | ||
# Edit at https://www.toptal.com/developers/gitignore?templates=go,goland,dotenv | ||
|
||
### dotenv ### | ||
.env | ||
|
||
### Go ### | ||
# If you prefer the allow list template instead of the deny list, see community template: | ||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore | ||
# | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, built with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Dependency directories (remove the comment below to include it) | ||
# vendor/ | ||
|
||
# Go workspace file | ||
go.work | ||
|
||
### GoLand ### | ||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider | ||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 | ||
|
||
# User-specific stuff | ||
.idea/** | ||
.idea/**/workspace.xml | ||
.idea/**/tasks.xml | ||
.idea/**/usage.statistics.xml | ||
.idea/**/dictionaries | ||
.idea/**/shelf | ||
|
||
# AWS User-specific | ||
.idea/**/aws.xml | ||
|
||
# Generated files | ||
.idea/**/contentModel.xml | ||
|
||
# Sensitive or high-churn files | ||
.idea/**/dataSources/ | ||
.idea/**/dataSources.ids | ||
.idea/**/dataSources.local.xml | ||
.idea/**/sqlDataSources.xml | ||
.idea/**/dynamic.xml | ||
.idea/**/uiDesigner.xml | ||
.idea/**/dbnavigator.xml | ||
|
||
# Gradle | ||
.idea/**/gradle.xml | ||
.idea/**/libraries | ||
|
||
# Gradle and Maven with auto-import | ||
# When using Gradle or Maven with auto-import, you should exclude module files, | ||
# since they will be recreated, and may cause churn. Uncomment if using | ||
# auto-import. | ||
# .idea/artifacts | ||
# .idea/compiler.xml | ||
# .idea/jarRepositories.xml | ||
# .idea/modules.xml | ||
# .idea/*.iml | ||
# .idea/modules | ||
# *.iml | ||
# *.ipr | ||
|
||
# CMake | ||
cmake-build-*/ | ||
|
||
# Mongo Explorer plugin | ||
.idea/**/mongoSettings.xml | ||
|
||
# File-based project format | ||
*.iws | ||
|
||
# IntelliJ | ||
out/ | ||
|
||
# mpeltonen/sbt-idea plugin | ||
.idea_modules/ | ||
|
||
# JIRA plugin | ||
atlassian-ide-plugin.xml | ||
|
||
# Cursive Clojure plugin | ||
.idea/replstate.xml | ||
|
||
# SonarLint plugin | ||
.idea/sonarlint/ | ||
|
||
# Crashlytics plugin (for Android Studio and IntelliJ) | ||
com_crashlytics_export_strings.xml | ||
crashlytics.properties | ||
crashlytics-build.properties | ||
fabric.properties | ||
|
||
# Editor-based Rest Client | ||
.idea/httpRequests | ||
|
||
# Android studio 3.1+ serialized cache file | ||
.idea/caches/build_file_checksums.ser | ||
|
||
### GoLand Patch ### | ||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 | ||
|
||
# *.iml | ||
# modules.xml | ||
# .idea/misc.xml | ||
# *.ipr | ||
|
||
# Sonarlint plugin | ||
# https://plugins.jetbrains.com/plugin/7973-sonarlint | ||
.idea/**/sonarlint/ | ||
|
||
# SonarQube Plugin | ||
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin | ||
.idea/**/sonarIssues.xml | ||
|
||
# Markdown Navigator plugin | ||
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced | ||
.idea/**/markdown-navigator.xml | ||
.idea/**/markdown-navigator-enh.xml | ||
.idea/**/markdown-navigator/ | ||
|
||
# Cache file creation bug | ||
# See https://youtrack.jetbrains.com/issue/JBR-2257 | ||
.idea/$CACHE_FILE$ | ||
|
||
# CodeStream plugin | ||
# https://plugins.jetbrains.com/plugin/12206-codestream | ||
.idea/codestream.xml | ||
|
||
# Azure Toolkit for IntelliJ plugin | ||
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij | ||
.idea/**/azureSettings.xml | ||
|
||
# End of https://www.toptal.com/developers/gitignore/api/go,goland,dotenv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
FROM golang:1.21-bullseye AS builder | ||
WORKDIR /src | ||
COPY . /src | ||
|
||
RUN go mod download | ||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags '-w -s' -o ./build/app ./main.go ./message.go | ||
|
||
FROM scratch | ||
|
||
COPY --from=builder /usr/share/zoneinfo/Asia/Tokyo /usr/share/zoneinfo/Asia/Tokyo | ||
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt | ||
|
||
COPY --from=builder /src/build/app /app | ||
ENTRYPOINT ["/app"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
module dns-mx-watchdog | ||
|
||
go 1.21 | ||
|
||
require ( | ||
github.com/gorilla/websocket v1.4.2 // indirect | ||
github.com/miekg/dns v1.1.56 // indirect | ||
github.com/slack-go/slack v0.12.3 // indirect | ||
golang.org/x/mod v0.12.0 // indirect | ||
golang.org/x/net v0.15.0 // indirect | ||
golang.org/x/sys v0.12.0 // indirect | ||
golang.org/x/tools v0.13.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= | ||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= | ||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= | ||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | ||
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= | ||
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/slack-go/slack v0.12.3 h1:92/dfFU8Q5XP6Wp5rr5/T5JHLM5c5Smtn53fhToAP88= | ||
github.com/slack-go/slack v0.12.3/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= | ||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= | ||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | ||
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= | ||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= | ||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= | ||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= | ||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= | ||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"github.com/miekg/dns" | ||
"github.com/slack-go/slack" | ||
"log" | ||
"os" | ||
"time" | ||
) | ||
|
||
func main() { | ||
token := os.Getenv("SLACK_BOT_TOKEN") | ||
channelId := os.Getenv("CHANNEL_ID") | ||
|
||
dnsServer := os.Getenv("DNS_SERVER") | ||
domain := os.Getenv("DOMAIN") | ||
|
||
client := slack.New(token) | ||
|
||
ticker := time.NewTicker(time.Millisecond * 60 * 60 * 1000) | ||
defer ticker.Stop() | ||
|
||
log.Printf("DNS Watchdog task has been started") | ||
|
||
count := 0 | ||
for { | ||
select { | ||
case <-ticker.C: | ||
log.Printf("count=%d\n", count) | ||
ok := lookupMXRecords(dnsServer, domain) | ||
if ok { | ||
count++ | ||
if count > 24 { | ||
count = 0 | ||
SendDailyNotification(*client, channelId, dnsServer, domain) | ||
} | ||
} else { | ||
count = 0 | ||
SendHourlyNotification(*client, channelId, dnsServer, domain) | ||
} | ||
} | ||
} | ||
} | ||
|
||
func lookupMXRecords(dnsServer string, domain string) bool { | ||
m := new(dns.Msg) | ||
m.SetQuestion(domain+".", dns.TypeMX) | ||
|
||
c := new(dns.Client) | ||
in, _, err := c.Exchange(m, dnsServer) | ||
if err != nil { | ||
fmt.Println("DNS Query Failed:", err) | ||
return false | ||
} | ||
|
||
for _, answer := range in.Answer { | ||
if mx, ok := answer.(*dns.MX); ok { | ||
fmt.Printf("Host: %s, Priority: %d\n", mx.Mx, mx.Preference) | ||
} | ||
} | ||
return true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"github.com/slack-go/slack" | ||
"log" | ||
"time" | ||
) | ||
|
||
func SendDailyNotification(client slack.Client, channelId string, dnsServer string, domain string) { | ||
attachment := slack.Attachment{ | ||
Title: "DNS MX Query Successful (daily report)", | ||
Color: "good", | ||
|
||
Fields: []slack.AttachmentField{ | ||
{ | ||
Title: "Domain", | ||
Value: "*" + domain + "*", | ||
Short: false, | ||
}, { | ||
Title: "DNS Server", | ||
Value: "*" + dnsServer + "*", | ||
Short: false, | ||
}, | ||
{ | ||
Title: "Date & Time", | ||
Value: time.Now().Format("2006/1/2 15:04"), | ||
Short: false, | ||
}, | ||
}, | ||
} | ||
|
||
_, _, err := client.PostMessage( | ||
channelId, | ||
slack.MsgOptionAttachments(attachment), | ||
slack.MsgOptionAsUser(true), | ||
) | ||
if err != nil { | ||
fmt.Printf("%s\n", err) | ||
return | ||
} | ||
log.Printf("[daily report] Message successfully sent to channel") | ||
} | ||
|
||
func SendHourlyNotification(client slack.Client, channelId string, dnsServer string, domain string) { | ||
attachment := slack.Attachment{ | ||
Pretext: "<!channel>", | ||
Title: "DNS MX Query FAILED (hourly report)", | ||
Color: "danger", | ||
|
||
Fields: []slack.AttachmentField{ | ||
{ | ||
Title: "Domain", | ||
Value: "*" + domain + "*", | ||
Short: false, | ||
}, { | ||
Title: "DNS Server", | ||
Value: "*" + dnsServer + "*", | ||
Short: false, | ||
}, | ||
{ | ||
Title: "Date & Time", | ||
Value: time.Now().Format("2006/1/2 15:04"), | ||
Short: false, | ||
}, | ||
}, | ||
} | ||
|
||
_, _, err := client.PostMessage( | ||
channelId, | ||
slack.MsgOptionAttachments(attachment), | ||
slack.MsgOptionAsUser(true), | ||
) | ||
if err != nil { | ||
fmt.Printf("%s\n", err) | ||
return | ||
} | ||
fmt.Printf("[hourly report] Message successfully sent to channel") | ||
} |