IP기반 Seed 데이터 생성, 업데이트에 반영

This commit is contained in:
Lectom C Han
2025-12-10 13:01:01 +09:00
parent 766a43f2e4
commit 869f912886
7 changed files with 6827 additions and 0 deletions

View File

@@ -35,6 +35,9 @@ func main() {
if err := userprogram.Sync(ctx, userprogram.SyncConfig{
MySQL: mysqlCfg,
DatabaseURL: dbURL,
Backend: userprogram.BackendFromEnv(),
LookupQuery: os.Getenv("GEOIP_LOOKUP_QUERY"),
MMDBPath: os.Getenv("GEOIP_DB_PATH"),
InitialCSV: paths.InitialCSV,
UpdateDir: paths.UpdateDir,
LogDir: paths.LogDir,

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,653 @@
"login_public_ip"
"14.48.84.141"
"211.234.204.251"
"117.111.6.13"
"211.198.190.49"
"211.235.72.178"
"1.235.81.27"
"114.200.179.133"
"121.184.7.188"
"211.234.192.13"
"211.235.72.147"
"218.158.86.157"
"125.133.48.195"
"112.161.155.175"
"183.99.124.97"
"220.66.76.78"
"121.191.223.33"
"125.138.71.211"
"59.11.165.82"
"115.178.65.26"
"211.235.91.226"
"59.10.150.245"
"211.234.207.159"
"115.21.217.190"
"211.234.201.231"
"118.47.158.73"
"211.227.202.187"
"211.107.218.58"
"211.216.248.115"
"220.66.76.90"
"182.229.32.154"
"220.66.75.59"
"211.234.180.197"
"110.13.11.131"
"121.191.17.213"
"61.255.88.218"
"175.223.11.244"
"1.239.250.231"
"220.66.76.12"
"220.77.100.238"
"220.82.170.73"
"121.169.76.48"
"106.101.1.212"
"140.174.179.52"
"59.14.240.38"
"220.66.76.27"
"220.86.36.184"
"125.142.226.122"
"211.230.115.75"
"106.246.182.243"
"27.171.216.148"
"218.158.239.173"
"118.33.187.225"
"59.16.104.87"
"147.46.92.180"
"59.16.73.144"
"14.40.91.101"
"106.101.3.30"
"211.253.98.34"
"58.232.80.152"
"121.184.234.136"
"183.100.230.19"
"175.204.180.9"
"61.78.80.26"
"118.36.229.195"
"220.66.76.86"
"222.120.70.104"
"119.196.164.92"
"156.59.47.103"
"147.46.91.174"
"59.151.192.104"
"211.234.192.53"
"118.42.197.237"
"202.150.191.177"
"110.70.51.111"
"121.139.50.83"
"147.46.91.171"
"147.46.92.184"
"147.46.91.170"
"61.73.2.206"
"59.31.157.91"
"110.8.170.18"
"106.244.132.248"
"211.192.150.114"
"115.22.123.154"
"211.234.195.205"
"211.234.207.45"
"114.108.4.68"
"14.56.254.183"
"220.66.76.34"
"210.121.223.76"
"180.80.112.236"
"147.46.91.163"
"118.216.73.120"
"59.29.126.221"
"14.7.55.231"
"211.244.123.114"
"220.121.164.74"
"147.46.91.167"
"115.138.239.234"
"121.157.84.116"
"147.46.92.169"
"121.135.102.173"
"220.90.89.151"
"119.204.165.88"
"147.46.91.138"
"147.46.91.150"
"211.235.72.16"
"121.153.208.177"
"121.132.197.222"
"183.99.111.70"
"223.39.177.150"
"147.46.91.168"
"147.46.91.130"
"211.234.192.51"
"121.164.134.117"
"211.226.165.121"
"182.208.205.103"
"58.224.147.180"
"220.66.76.25"
"220.125.153.37"
"156.59.47.87"
"220.66.75.19"
"220.66.76.97"
"211.235.83.117"
"115.95.35.118"
"147.46.92.183"
"211.234.201.160"
"147.46.92.75"
"221.153.165.116"
"147.46.91.156"
"147.46.91.161"
"61.85.224.4"
"106.101.130.197"
"220.74.62.74"
"121.180.83.184"
"220.77.186.166"
"112.166.96.247"
"175.210.109.187"
"125.129.140.58"
"220.66.76.95"
"211.234.197.119"
"220.66.75.146"
"1.235.32.245"
"49.142.69.179"
"218.146.23.149"
"14.34.247.171"
"125.135.247.165"
"211.234.226.128"
"211.234.200.241"
"106.101.0.195"
"218.153.177.253"
"211.235.72.65"
"221.154.56.116"
"220.66.76.16"
"39.127.71.122"
"222.105.23.150"
"223.39.219.99"
"220.90.15.33"
"121.149.50.106"
"121.64.161.83"
"211.235.65.89"
"140.174.179.101"
"39.7.47.68"
"211.218.250.217"
"221.138.240.198"
"106.101.9.220"
"220.66.76.29"
"211.198.63.117"
"147.46.91.145"
"211.221.180.2"
"59.186.123.155"
"58.77.140.10"
"222.239.194.164"
"220.66.75.28"
"27.165.137.52"
"175.223.26.63"
"121.141.47.152"
"125.133.34.162"
"147.46.92.177"
"223.39.212.136"
"147.46.91.141"
"220.116.237.88"
"106.101.11.6"
"125.242.55.17"
"106.101.128.56"
"210.117.14.133"
"156.59.47.101"
"147.46.92.84"
"118.221.140.2"
"211.36.143.98"
"106.101.136.2"
"220.78.198.149"
"147.46.92.182"
"59.186.123.246"
"112.163.158.164"
"61.81.132.10"
"117.111.21.63"
"140.174.179.5"
"121.151.201.239"
"182.215.120.69"
"218.144.247.3"
"116.33.55.218"
"147.46.91.137"
"220.66.75.39"
"220.117.8.14"
"175.223.26.207"
"116.34.125.138"
"1.241.69.200"
"211.234.194.156"
"121.138.66.189"
"210.105.187.27"
"221.160.85.228"
"58.237.207.130"
"220.66.76.24"
"211.234.192.81"
"122.44.13.14"
"220.66.76.11"
"117.111.14.205"
"125.248.23.189"
"118.35.141.164"
"210.99.28.101"
"119.197.226.84"
"211.234.203.248"
"1.247.148.164"
"61.39.66.227"
"112.161.208.191"
"175.213.178.48"
"14.35.204.124"
"211.234.188.148"
"211.234.199.137"
"1.238.107.99"
"119.206.79.88"
"147.46.35.247"
"106.101.1.8"
"223.39.176.122"
"222.103.33.142"
"110.70.47.11"
"114.108.4.72"
"147.46.91.177"
"220.74.14.94"
"211.234.194.250"
"112.158.34.172"
"112.170.16.221"
"221.161.34.243"
"59.1.172.178"
"147.46.92.195"
"121.148.130.230"
"220.121.167.216"
"115.89.238.220"
"220.74.97.67"
"222.99.115.189"
"112.218.197.242"
"156.59.47.105"
"106.101.3.174"
"114.108.4.74"
"211.36.152.1"
"110.70.54.119"
"211.36.152.88"
"211.218.206.137"
"211.222.129.21"
"218.148.114.204"
"156.59.47.89"
"156.59.47.102"
"221.159.100.39"
"210.206.95.190"
"223.39.176.221"
"125.137.245.86"
"118.44.169.233"
"211.185.247.104"
"175.121.118.4"
"125.136.144.163"
"61.77.58.136"
"222.110.160.71"
"14.39.86.155"
"211.36.158.211"
"112.164.250.69"
"1.235.111.48"
"223.39.219.238"
"211.36.159.30"
"223.39.174.191"
"106.248.204.158"
"211.234.198.196"
"114.203.88.3"
"211.109.114.59"
"125.130.142.245"
"222.116.153.103"
"58.227.62.3"
"121.188.105.131"
"121.188.98.4"
"118.235.88.163"
"110.35.50.202"
"175.204.137.93"
"14.45.119.89"
"59.8.140.188"
"59.0.82.13"
"147.46.91.134"
"211.36.152.213"
"140.174.179.54"
"147.46.91.155"
"106.101.9.19"
"147.46.91.136"
"211.234.188.82"
"223.39.219.31"
"27.166.222.166"
"118.44.178.75"
"121.187.10.74"
"210.204.169.25"
"218.152.55.210"
"118.39.26.132"
"147.46.91.162"
"61.82.142.93"
"147.46.91.169"
"147.46.91.148"
"211.185.247.57"
"121.66.158.246"
"59.1.229.49"
"119.207.27.75"
"118.235.13.218"
"106.101.11.31"
"203.228.37.61"
"121.177.226.29"
"211.36.142.3"
"175.197.85.244"
"115.23.63.15"
"220.149.222.50"
"112.164.121.147"
"112.170.151.209"
"220.76.77.96"
"59.27.94.66"
"211.234.181.75"
"220.70.176.152"
"112.187.54.166"
"220.66.76.85"
"125.132.106.239"
"147.46.92.153"
"121.151.201.47"
"211.211.117.44"
"211.253.98.18"
"223.39.218.48"
"116.121.107.104"
"110.70.54.144"
"211.235.82.41"
"211.193.241.72"
"220.84.21.5"
"147.46.91.140"
"117.111.12.85"
"39.125.46.181"
"220.66.76.22"
"223.53.98.220"
"147.46.92.67"
"211.36.136.245"
"220.66.76.81"
"222.114.41.134"
"211.48.217.138"
"42.27.139.140"
"220.66.76.89"
"175.223.19.27"
"223.39.218.24"
"147.46.91.146"
"119.207.166.243"
"14.53.188.21"
"147.46.92.81"
"147.46.91.149"
"27.168.114.250"
"118.37.166.161"
"211.234.181.59"
"125.179.210.215"
"211.223.112.37"
"211.235.74.158"
"117.111.5.23"
"106.101.2.36"
"211.54.94.161"
"42.20.3.222"
"211.234.226.189"
"211.234.180.75"
"147.46.92.69"
"211.234.203.21"
"39.7.54.240"
"210.93.112.123"
"123.111.42.110"
"119.204.117.36"
"220.83.108.31"
"223.39.218.193"
"147.46.91.143"
"222.107.72.242"
"140.174.179.105"
"220.66.75.91"
"223.39.215.148"
"147.46.91.166"
"147.46.91.157"
"121.187.162.200"
"119.196.119.220"
"211.108.72.139"
"106.101.10.48"
"211.196.60.173"
"14.33.76.159"
"59.3.140.180"
"175.196.195.93"
"156.59.47.84"
"121.157.148.27"
"211.54.213.71"
"220.89.134.177"
"106.101.2.74"
"121.177.240.182"
"222.121.148.227"
"119.195.149.96"
"211.235.66.78"
"220.66.76.114"
"14.51.248.237"
"117.111.6.3"
"220.66.76.249"
"211.234.197.154"
"218.232.187.68"
"221.154.0.234"
"211.219.72.198"
"59.23.24.93"
"112.167.22.71"
"112.162.165.45"
"61.98.205.242"
"218.157.197.208"
"59.186.123.237"
"220.124.17.116"
"121.161.151.28"
"211.106.83.170"
"220.66.76.21"
"220.66.75.147"
"220.121.253.183"
"14.35.122.213"
"211.234.202.228"
"121.136.241.72"
"221.165.252.99"
"175.223.39.226"
"106.101.1.169"
"59.22.166.228"
"118.235.74.207"
"218.153.99.248"
"211.169.233.104"
"58.73.175.11"
"175.210.233.213"
"121.188.1.125"
"211.234.227.38"
"116.121.101.233"
"211.234.201.135"
"147.46.91.88"
"125.242.55.15"
"211.234.227.148"
"180.65.219.52"
"112.167.22.15"
"222.118.36.105"
"220.93.249.247"
"61.85.177.75"
"220.93.204.199"
"211.234.204.13"
"211.234.200.217"
"121.169.114.68"
"220.66.76.26"
"223.39.219.47"
"220.78.14.27"
"59.2.190.227"
"58.236.57.152"
"175.194.216.115"
"210.222.164.40"
"14.36.217.161"
"61.78.80.148"
"147.46.91.142"
"59.21.93.51"
"112.166.253.199"
"121.66.57.91"
"211.234.203.150"
"168.126.136.68"
"106.101.2.252"
"140.174.179.37"
"49.175.164.136"
"59.11.2.104"
"223.39.202.254"
"183.100.80.51"
"42.19.21.126"
"220.66.76.98"
"219.251.6.155"
"121.135.117.130"
"112.186.236.215"
"14.52.96.21"
"211.36.145.170"
"118.43.43.39"
"222.102.162.27"
"211.234.204.209"
"115.138.239.252"
"223.39.207.59"
"110.70.47.253"
"147.46.92.175"
"211.235.82.89"
"218.145.201.114"
"169.211.153.84"
"211.54.188.233"
"140.174.179.7"
"121.149.3.47"
"118.42.56.19"
"211.234.200.239"
"14.35.229.40"
"222.98.49.97"
"14.53.69.245"
"220.66.76.79"
"147.46.92.93"
"211.196.60.230"
"223.38.94.117"
"27.179.218.211"
"211.170.25.65"
"119.203.157.49"
"220.66.76.91"
"118.235.74.19"
"61.43.126.201"
"220.66.75.120"
"59.26.59.41"
"118.235.81.217"
"147.46.92.179"
"1.240.55.8"
"220.71.159.105"
"1.217.176.218"
"114.71.128.87"
"124.50.176.34"
"147.46.91.131"
"108.181.53.234"
"211.198.89.114"
"116.125.137.239"
"183.98.129.158"
"59.13.18.98"
"147.47.202.18"
"211.234.205.141"
"58.150.67.157"
"220.66.76.187"
"211.215.11.165"
"175.209.199.226"
"211.234.206.165"
"106.252.47.68"
"59.19.225.21"
"121.185.248.189"
"110.35.154.135"
"112.173.236.204"
"147.46.91.151"
"211.177.40.198"
"59.3.164.233"
"106.101.133.232"
"42.22.207.68"
"14.47.241.67"
"118.235.73.87"
"59.26.225.202"
"61.83.185.245"
"121.169.114.207"
"112.168.110.147"
"147.46.92.113"
"112.170.153.89"
"211.34.121.59"
"222.232.200.179"
"147.46.92.171"
"59.29.17.192"
"222.103.222.144"
"222.112.53.139"
"147.46.91.160"
"1.241.255.157"
"147.46.91.129"
"14.48.158.224"
"211.39.65.160"
"116.124.153.130"
"223.57.95.239"
"106.101.3.193"
"211.50.13.130"
"218.150.119.207"
"221.156.11.154"
"211.218.253.1"
"220.116.71.64"
"147.46.92.173"
"210.204.169.106"
"59.0.165.173"
"124.63.32.14"
"211.234.180.120"
"140.174.179.38"
"211.235.91.16"
"220.66.75.129"
"147.46.91.61"
"175.223.34.69"
"119.193.183.73"
"1.212.25.154"
"106.101.0.26"
"14.48.58.175"
"203.231.144.61"
"211.235.82.193"
"59.28.27.189"
"222.101.203.48"
"175.206.14.81"
"220.66.76.23"
"211.234.192.25"
"121.139.197.234"
"147.46.91.158"
"118.45.86.71"
"121.162.82.93"
"121.136.197.44"
"211.228.5.235"
"220.66.76.19"
"147.46.92.71"
"220.125.6.119"
"59.21.195.163"
"106.101.128.18"
"59.12.200.34"
"211.231.46.88"
"147.46.91.139"
"220.66.75.25"
"123.214.63.222"
"118.235.85.152"
"59.186.123.249"
"121.190.157.218"
"223.39.218.74"
"121.143.215.121"
"61.254.28.177"
"61.98.205.243"
"115.138.209.44"
"211.234.195.169"
"59.186.123.226"
"211.108.69.179"
"27.163.144.150"
"14.34.247.68"
"121.185.152.100"
"140.174.179.56"
"118.223.231.46"
"175.208.232.133"
"147.46.91.175"
"175.223.39.20"
"121.124.88.96"
"140.174.179.102"
"222.98.163.179"
"119.207.37.231"
"147.46.91.165"
"59.17.243.62"
"14.46.56.26"
"59.26.225.230"
"42.22.217.197"
"125.186.69.146"
"211.234.199.135"
"221.150.16.242"
"121.124.172.71"
"147.46.91.173"
"147.46.92.152"
"108.181.53.228"
"220.66.76.17"
"1.226.226.50"
"223.39.218.225"
"147.46.92.176"
"58.79.5.215"
"125.131.30.128"
"61.75.98.148"
"114.71.128.111"
"211.223.30.241"
"119.207.221.210"
1 login_public_ip
2 14.48.84.141
3 211.234.204.251
4 117.111.6.13
5 211.198.190.49
6 211.235.72.178
7 1.235.81.27
8 114.200.179.133
9 121.184.7.188
10 211.234.192.13
11 211.235.72.147
12 218.158.86.157
13 125.133.48.195
14 112.161.155.175
15 183.99.124.97
16 220.66.76.78
17 121.191.223.33
18 125.138.71.211
19 59.11.165.82
20 115.178.65.26
21 211.235.91.226
22 59.10.150.245
23 211.234.207.159
24 115.21.217.190
25 211.234.201.231
26 118.47.158.73
27 211.227.202.187
28 211.107.218.58
29 211.216.248.115
30 220.66.76.90
31 182.229.32.154
32 220.66.75.59
33 211.234.180.197
34 110.13.11.131
35 121.191.17.213
36 61.255.88.218
37 175.223.11.244
38 1.239.250.231
39 220.66.76.12
40 220.77.100.238
41 220.82.170.73
42 121.169.76.48
43 106.101.1.212
44 140.174.179.52
45 59.14.240.38
46 220.66.76.27
47 220.86.36.184
48 125.142.226.122
49 211.230.115.75
50 106.246.182.243
51 27.171.216.148
52 218.158.239.173
53 118.33.187.225
54 59.16.104.87
55 147.46.92.180
56 59.16.73.144
57 14.40.91.101
58 106.101.3.30
59 211.253.98.34
60 58.232.80.152
61 121.184.234.136
62 183.100.230.19
63 175.204.180.9
64 61.78.80.26
65 118.36.229.195
66 220.66.76.86
67 222.120.70.104
68 119.196.164.92
69 156.59.47.103
70 147.46.91.174
71 59.151.192.104
72 211.234.192.53
73 118.42.197.237
74 202.150.191.177
75 110.70.51.111
76 121.139.50.83
77 147.46.91.171
78 147.46.92.184
79 147.46.91.170
80 61.73.2.206
81 59.31.157.91
82 110.8.170.18
83 106.244.132.248
84 211.192.150.114
85 115.22.123.154
86 211.234.195.205
87 211.234.207.45
88 114.108.4.68
89 14.56.254.183
90 220.66.76.34
91 210.121.223.76
92 180.80.112.236
93 147.46.91.163
94 118.216.73.120
95 59.29.126.221
96 14.7.55.231
97 211.244.123.114
98 220.121.164.74
99 147.46.91.167
100 115.138.239.234
101 121.157.84.116
102 147.46.92.169
103 121.135.102.173
104 220.90.89.151
105 119.204.165.88
106 147.46.91.138
107 147.46.91.150
108 211.235.72.16
109 121.153.208.177
110 121.132.197.222
111 183.99.111.70
112 223.39.177.150
113 147.46.91.168
114 147.46.91.130
115 211.234.192.51
116 121.164.134.117
117 211.226.165.121
118 182.208.205.103
119 58.224.147.180
120 220.66.76.25
121 220.125.153.37
122 156.59.47.87
123 220.66.75.19
124 220.66.76.97
125 211.235.83.117
126 115.95.35.118
127 147.46.92.183
128 211.234.201.160
129 147.46.92.75
130 221.153.165.116
131 147.46.91.156
132 147.46.91.161
133 61.85.224.4
134 106.101.130.197
135 220.74.62.74
136 121.180.83.184
137 220.77.186.166
138 112.166.96.247
139 175.210.109.187
140 125.129.140.58
141 220.66.76.95
142 211.234.197.119
143 220.66.75.146
144 1.235.32.245
145 49.142.69.179
146 218.146.23.149
147 14.34.247.171
148 125.135.247.165
149 211.234.226.128
150 211.234.200.241
151 106.101.0.195
152 218.153.177.253
153 211.235.72.65
154 221.154.56.116
155 220.66.76.16
156 39.127.71.122
157 222.105.23.150
158 223.39.219.99
159 220.90.15.33
160 121.149.50.106
161 121.64.161.83
162 211.235.65.89
163 140.174.179.101
164 39.7.47.68
165 211.218.250.217
166 221.138.240.198
167 106.101.9.220
168 220.66.76.29
169 211.198.63.117
170 147.46.91.145
171 211.221.180.2
172 59.186.123.155
173 58.77.140.10
174 222.239.194.164
175 220.66.75.28
176 27.165.137.52
177 175.223.26.63
178 121.141.47.152
179 125.133.34.162
180 147.46.92.177
181 223.39.212.136
182 147.46.91.141
183 220.116.237.88
184 106.101.11.6
185 125.242.55.17
186 106.101.128.56
187 210.117.14.133
188 156.59.47.101
189 147.46.92.84
190 118.221.140.2
191 211.36.143.98
192 106.101.136.2
193 220.78.198.149
194 147.46.92.182
195 59.186.123.246
196 112.163.158.164
197 61.81.132.10
198 117.111.21.63
199 140.174.179.5
200 121.151.201.239
201 182.215.120.69
202 218.144.247.3
203 116.33.55.218
204 147.46.91.137
205 220.66.75.39
206 220.117.8.14
207 175.223.26.207
208 116.34.125.138
209 1.241.69.200
210 211.234.194.156
211 121.138.66.189
212 210.105.187.27
213 221.160.85.228
214 58.237.207.130
215 220.66.76.24
216 211.234.192.81
217 122.44.13.14
218 220.66.76.11
219 117.111.14.205
220 125.248.23.189
221 118.35.141.164
222 210.99.28.101
223 119.197.226.84
224 211.234.203.248
225 1.247.148.164
226 61.39.66.227
227 112.161.208.191
228 175.213.178.48
229 14.35.204.124
230 211.234.188.148
231 211.234.199.137
232 1.238.107.99
233 119.206.79.88
234 147.46.35.247
235 106.101.1.8
236 223.39.176.122
237 222.103.33.142
238 110.70.47.11
239 114.108.4.72
240 147.46.91.177
241 220.74.14.94
242 211.234.194.250
243 112.158.34.172
244 112.170.16.221
245 221.161.34.243
246 59.1.172.178
247 147.46.92.195
248 121.148.130.230
249 220.121.167.216
250 115.89.238.220
251 220.74.97.67
252 222.99.115.189
253 112.218.197.242
254 156.59.47.105
255 106.101.3.174
256 114.108.4.74
257 211.36.152.1
258 110.70.54.119
259 211.36.152.88
260 211.218.206.137
261 211.222.129.21
262 218.148.114.204
263 156.59.47.89
264 156.59.47.102
265 221.159.100.39
266 210.206.95.190
267 223.39.176.221
268 125.137.245.86
269 118.44.169.233
270 211.185.247.104
271 175.121.118.4
272 125.136.144.163
273 61.77.58.136
274 222.110.160.71
275 14.39.86.155
276 211.36.158.211
277 112.164.250.69
278 1.235.111.48
279 223.39.219.238
280 211.36.159.30
281 223.39.174.191
282 106.248.204.158
283 211.234.198.196
284 114.203.88.3
285 211.109.114.59
286 125.130.142.245
287 222.116.153.103
288 58.227.62.3
289 121.188.105.131
290 121.188.98.4
291 118.235.88.163
292 110.35.50.202
293 175.204.137.93
294 14.45.119.89
295 59.8.140.188
296 59.0.82.13
297 147.46.91.134
298 211.36.152.213
299 140.174.179.54
300 147.46.91.155
301 106.101.9.19
302 147.46.91.136
303 211.234.188.82
304 223.39.219.31
305 27.166.222.166
306 118.44.178.75
307 121.187.10.74
308 210.204.169.25
309 218.152.55.210
310 118.39.26.132
311 147.46.91.162
312 61.82.142.93
313 147.46.91.169
314 147.46.91.148
315 211.185.247.57
316 121.66.158.246
317 59.1.229.49
318 119.207.27.75
319 118.235.13.218
320 106.101.11.31
321 203.228.37.61
322 121.177.226.29
323 211.36.142.3
324 175.197.85.244
325 115.23.63.15
326 220.149.222.50
327 112.164.121.147
328 112.170.151.209
329 220.76.77.96
330 59.27.94.66
331 211.234.181.75
332 220.70.176.152
333 112.187.54.166
334 220.66.76.85
335 125.132.106.239
336 147.46.92.153
337 121.151.201.47
338 211.211.117.44
339 211.253.98.18
340 223.39.218.48
341 116.121.107.104
342 110.70.54.144
343 211.235.82.41
344 211.193.241.72
345 220.84.21.5
346 147.46.91.140
347 117.111.12.85
348 39.125.46.181
349 220.66.76.22
350 223.53.98.220
351 147.46.92.67
352 211.36.136.245
353 220.66.76.81
354 222.114.41.134
355 211.48.217.138
356 42.27.139.140
357 220.66.76.89
358 175.223.19.27
359 223.39.218.24
360 147.46.91.146
361 119.207.166.243
362 14.53.188.21
363 147.46.92.81
364 147.46.91.149
365 27.168.114.250
366 118.37.166.161
367 211.234.181.59
368 125.179.210.215
369 211.223.112.37
370 211.235.74.158
371 117.111.5.23
372 106.101.2.36
373 211.54.94.161
374 42.20.3.222
375 211.234.226.189
376 211.234.180.75
377 147.46.92.69
378 211.234.203.21
379 39.7.54.240
380 210.93.112.123
381 123.111.42.110
382 119.204.117.36
383 220.83.108.31
384 223.39.218.193
385 147.46.91.143
386 222.107.72.242
387 140.174.179.105
388 220.66.75.91
389 223.39.215.148
390 147.46.91.166
391 147.46.91.157
392 121.187.162.200
393 119.196.119.220
394 211.108.72.139
395 106.101.10.48
396 211.196.60.173
397 14.33.76.159
398 59.3.140.180
399 175.196.195.93
400 156.59.47.84
401 121.157.148.27
402 211.54.213.71
403 220.89.134.177
404 106.101.2.74
405 121.177.240.182
406 222.121.148.227
407 119.195.149.96
408 211.235.66.78
409 220.66.76.114
410 14.51.248.237
411 117.111.6.3
412 220.66.76.249
413 211.234.197.154
414 218.232.187.68
415 221.154.0.234
416 211.219.72.198
417 59.23.24.93
418 112.167.22.71
419 112.162.165.45
420 61.98.205.242
421 218.157.197.208
422 59.186.123.237
423 220.124.17.116
424 121.161.151.28
425 211.106.83.170
426 220.66.76.21
427 220.66.75.147
428 220.121.253.183
429 14.35.122.213
430 211.234.202.228
431 121.136.241.72
432 221.165.252.99
433 175.223.39.226
434 106.101.1.169
435 59.22.166.228
436 118.235.74.207
437 218.153.99.248
438 211.169.233.104
439 58.73.175.11
440 175.210.233.213
441 121.188.1.125
442 211.234.227.38
443 116.121.101.233
444 211.234.201.135
445 147.46.91.88
446 125.242.55.15
447 211.234.227.148
448 180.65.219.52
449 112.167.22.15
450 222.118.36.105
451 220.93.249.247
452 61.85.177.75
453 220.93.204.199
454 211.234.204.13
455 211.234.200.217
456 121.169.114.68
457 220.66.76.26
458 223.39.219.47
459 220.78.14.27
460 59.2.190.227
461 58.236.57.152
462 175.194.216.115
463 210.222.164.40
464 14.36.217.161
465 61.78.80.148
466 147.46.91.142
467 59.21.93.51
468 112.166.253.199
469 121.66.57.91
470 211.234.203.150
471 168.126.136.68
472 106.101.2.252
473 140.174.179.37
474 49.175.164.136
475 59.11.2.104
476 223.39.202.254
477 183.100.80.51
478 42.19.21.126
479 220.66.76.98
480 219.251.6.155
481 121.135.117.130
482 112.186.236.215
483 14.52.96.21
484 211.36.145.170
485 118.43.43.39
486 222.102.162.27
487 211.234.204.209
488 115.138.239.252
489 223.39.207.59
490 110.70.47.253
491 147.46.92.175
492 211.235.82.89
493 218.145.201.114
494 169.211.153.84
495 211.54.188.233
496 140.174.179.7
497 121.149.3.47
498 118.42.56.19
499 211.234.200.239
500 14.35.229.40
501 222.98.49.97
502 14.53.69.245
503 220.66.76.79
504 147.46.92.93
505 211.196.60.230
506 223.38.94.117
507 27.179.218.211
508 211.170.25.65
509 119.203.157.49
510 220.66.76.91
511 118.235.74.19
512 61.43.126.201
513 220.66.75.120
514 59.26.59.41
515 118.235.81.217
516 147.46.92.179
517 1.240.55.8
518 220.71.159.105
519 1.217.176.218
520 114.71.128.87
521 124.50.176.34
522 147.46.91.131
523 108.181.53.234
524 211.198.89.114
525 116.125.137.239
526 183.98.129.158
527 59.13.18.98
528 147.47.202.18
529 211.234.205.141
530 58.150.67.157
531 220.66.76.187
532 211.215.11.165
533 175.209.199.226
534 211.234.206.165
535 106.252.47.68
536 59.19.225.21
537 121.185.248.189
538 110.35.154.135
539 112.173.236.204
540 147.46.91.151
541 211.177.40.198
542 59.3.164.233
543 106.101.133.232
544 42.22.207.68
545 14.47.241.67
546 118.235.73.87
547 59.26.225.202
548 61.83.185.245
549 121.169.114.207
550 112.168.110.147
551 147.46.92.113
552 112.170.153.89
553 211.34.121.59
554 222.232.200.179
555 147.46.92.171
556 59.29.17.192
557 222.103.222.144
558 222.112.53.139
559 147.46.91.160
560 1.241.255.157
561 147.46.91.129
562 14.48.158.224
563 211.39.65.160
564 116.124.153.130
565 223.57.95.239
566 106.101.3.193
567 211.50.13.130
568 218.150.119.207
569 221.156.11.154
570 211.218.253.1
571 220.116.71.64
572 147.46.92.173
573 210.204.169.106
574 59.0.165.173
575 124.63.32.14
576 211.234.180.120
577 140.174.179.38
578 211.235.91.16
579 220.66.75.129
580 147.46.91.61
581 175.223.34.69
582 119.193.183.73
583 1.212.25.154
584 106.101.0.26
585 14.48.58.175
586 203.231.144.61
587 211.235.82.193
588 59.28.27.189
589 222.101.203.48
590 175.206.14.81
591 220.66.76.23
592 211.234.192.25
593 121.139.197.234
594 147.46.91.158
595 118.45.86.71
596 121.162.82.93
597 121.136.197.44
598 211.228.5.235
599 220.66.76.19
600 147.46.92.71
601 220.125.6.119
602 59.21.195.163
603 106.101.128.18
604 59.12.200.34
605 211.231.46.88
606 147.46.91.139
607 220.66.75.25
608 123.214.63.222
609 118.235.85.152
610 59.186.123.249
611 121.190.157.218
612 223.39.218.74
613 121.143.215.121
614 61.254.28.177
615 61.98.205.243
616 115.138.209.44
617 211.234.195.169
618 59.186.123.226
619 211.108.69.179
620 27.163.144.150
621 14.34.247.68
622 121.185.152.100
623 140.174.179.56
624 118.223.231.46
625 175.208.232.133
626 147.46.91.175
627 175.223.39.20
628 121.124.88.96
629 140.174.179.102
630 222.98.163.179
631 119.207.37.231
632 147.46.91.165
633 59.17.243.62
634 14.46.56.26
635 59.26.225.230
636 42.22.217.197
637 125.186.69.146
638 211.234.199.135
639 221.150.16.242
640 121.124.172.71
641 147.46.91.173
642 147.46.92.152
643 108.181.53.228
644 220.66.76.17
645 1.226.226.50
646 223.39.218.225
647 147.46.92.176
648 58.79.5.215
649 125.131.30.128
650 61.75.98.148
651 114.71.128.111
652 211.223.30.241
653 119.207.221.210

View File

@@ -1,12 +1,23 @@
package userprogram
import (
"errors"
"fmt"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
"geoip-rest/internal/geo"
)
type Backend string
const (
BackendMMDB Backend = "mmdb"
BackendPostgres Backend = "postgres"
)
const (
@@ -88,6 +99,42 @@ func NewPathsFromEnv() (Paths, error) {
return paths, nil
}
func BackendFromEnv() Backend {
val := strings.ToLower(env("GEOIP_BACKEND", string(BackendMMDB)))
switch val {
case string(BackendMMDB), "":
return BackendMMDB
case string(BackendPostgres):
return BackendPostgres
default:
return BackendMMDB
}
}
func ResolveBackend(cfg geo.Config) (geo.Resolver, error) {
switch Backend(cfg.Backend) {
case BackendMMDB, "":
if cfg.MMDBPath == "" {
return nil, errors.New("MMDBPath required for mmdb backend")
}
return geo.NewResolver(geo.Config{
Backend: geo.BackendMMDB,
MMDBPath: cfg.MMDBPath,
})
case BackendPostgres:
if cfg.DatabaseURL == "" {
return nil, errors.New("DatabaseURL required for postgres backend")
}
return geo.NewResolver(geo.Config{
Backend: geo.BackendPostgres,
DatabaseURL: cfg.DatabaseURL,
LookupQuery: cfg.LookupQuery,
})
default:
return nil, fmt.Errorf("unsupported backend %s", cfg.Backend)
}
}
func ParseTargetDate(raw string) (time.Time, error) {
if raw == "" {
return yesterdayKST(), nil

View File

@@ -0,0 +1,192 @@
package userprogram
import (
"context"
"fmt"
"net"
"os"
"path/filepath"
"sort"
"strings"
"time"
"github.com/jackc/pgx/v5"
"geoip-rest/internal/geo"
)
func EnsureIPGeoInfoTable(ctx context.Context, conn *pgx.Conn, schema string) error {
ddl := fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s.ip_geoinfo (
id bigserial PRIMARY KEY,
ip inet UNIQUE NOT NULL,
country text,
region text,
city text,
address text,
latitude double precision,
longitude double precision
);`, pgx.Identifier{schema}.Sanitize())
_, err := conn.Exec(ctx, ddl)
return err
}
// ExportPublicIPs writes distinct login_public_ip values to a CSV file with header.
func ExportPublicIPs(ctx context.Context, conn *pgx.Conn, schema, path string) error {
rows, err := conn.Query(ctx, fmt.Sprintf(`
SELECT DISTINCT login_public_ip
FROM %s.user_program_info_replica
WHERE login_public_ip IS NOT NULL AND login_public_ip <> ''
ORDER BY login_public_ip;`, pgx.Identifier{schema}.Sanitize()))
if err != nil {
return err
}
defer rows.Close()
var ips []string
for rows.Next() {
var ip string
if err := rows.Scan(&ip); err != nil {
return err
}
ips = append(ips, ip)
}
if rows.Err() != nil {
return rows.Err()
}
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return err
}
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
if _, err := f.WriteString(`"login_public_ip"` + "\n"); err != nil {
return err
}
for _, ip := range ips {
if _, err := f.WriteString(fmt.Sprintf(`"%s"`+"\n", ip)); err != nil {
return err
}
}
return nil
}
// GenerateIPGeoInfoSQL builds an upsert SQL file for IPs. If onlyNew is true, it skips
// IPs already present in ip_geoinfo.
func GenerateIPGeoInfoSQL(ctx context.Context, conn *pgx.Conn, schema string, resolver geo.Resolver, output string, onlyNew bool) (int, error) {
query := fmt.Sprintf(`
SELECT DISTINCT login_public_ip
FROM %s.user_program_info_replica r
WHERE login_public_ip IS NOT NULL AND login_public_ip <> ''`, pgx.Identifier{schema}.Sanitize())
if onlyNew {
query += fmt.Sprintf(`
AND NOT EXISTS (
SELECT 1 FROM %s.ip_geoinfo g WHERE g.ip = r.login_public_ip::inet
)`, pgx.Identifier{schema}.Sanitize())
}
query += ";"
rows, err := conn.Query(ctx, query)
if err != nil {
return 0, err
}
defer rows.Close()
var ips []string
for rows.Next() {
var ip string
if err := rows.Scan(&ip); err != nil {
return 0, err
}
ips = append(ips, ip)
}
if rows.Err() != nil {
return 0, rows.Err()
}
if len(ips) == 0 {
return 0, nil
}
sort.Strings(ips)
if err := os.MkdirAll(filepath.Dir(output), 0o755); err != nil {
return 0, err
}
f, err := os.Create(output)
if err != nil {
return 0, err
}
defer f.Close()
header := fmt.Sprintf("-- generated at %s KST\n", time.Now().In(kst()).Format(time.RFC3339))
header += fmt.Sprintf("CREATE SCHEMA IF NOT EXISTS %s;\n", schemaIdent(schema))
header += fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s.ip_geoinfo (
id bigserial PRIMARY KEY,
ip inet UNIQUE NOT NULL,
country text,
region text,
city text,
address text,
latitude double precision,
longitude double precision
);`+"\n", schemaIdent(schema))
if _, err := f.WriteString(header); err != nil {
return 0, err
}
count := 0
for _, ip := range ips {
loc, err := resolver.Lookup(ip)
if err != nil {
continue
}
stmt := fmt.Sprintf(`INSERT INTO %s.ip_geoinfo (ip, country, region, city, address, latitude, longitude)
VALUES ('%s', %s, %s, %s, %s, %f, %f)
ON CONFLICT (ip) DO UPDATE SET
country = EXCLUDED.country,
region = EXCLUDED.region,
city = EXCLUDED.city,
address = EXCLUDED.address,
latitude = EXCLUDED.latitude,
longitude = EXCLUDED.longitude;
`, schemaIdent(schema), toHostCIDR(ip), quote(loc.Country), quote(loc.Region), quote(loc.City), quote(loc.Address), loc.Latitude, loc.Longitude)
if _, err := f.WriteString(stmt); err != nil {
return count, err
}
count++
}
return count, nil
}
func ExecuteSQLFile(ctx context.Context, conn *pgx.Conn, path string) error {
content, err := os.ReadFile(path)
if err != nil {
return err
}
_, err = conn.Exec(ctx, string(content))
return err
}
func toHostCIDR(ipStr string) string {
ip := net.ParseIP(ipStr)
if ip == nil {
return ""
}
if ip.To4() != nil {
return ip.String() + "/32"
}
return ip.String() + "/128"
}
func quote(s string) string {
return fmt.Sprintf("'%s'", strings.ReplaceAll(s, "'", "''"))
}
func schemaIdent(s string) string {
return `"` + strings.ReplaceAll(s, `"`, `""`) + `"`
}

View File

@@ -4,16 +4,23 @@ import (
"context"
"fmt"
"log"
"path/filepath"
"time"
"github.com/jackc/pgx/v5"
"geoip-rest/internal/geo"
"geoip-rest/internal/importer"
)
const defaultMMDBPath = "/initial_data/GeoLite2-City.mmdb"
type SyncConfig struct {
MySQL MySQLConfig
DatabaseURL string
Backend Backend
MMDBPath string
LookupQuery string
InitialCSV string
UpdateDir string
LogDir string
@@ -34,6 +41,9 @@ func (c *SyncConfig) defaults() {
if c.Schema == "" {
c.Schema = DefaultSchema
}
if c.MMDBPath == "" {
c.MMDBPath = defaultMMDBPath
}
if c.Logger == nil {
c.Logger = log.Default()
}
@@ -90,6 +100,10 @@ func Sync(ctx context.Context, cfg SyncConfig) error {
return fmt.Errorf("import updates: %w", err)
}
if err := ensureIPGeoInfo(ctx, cfg, conn); err != nil {
cfg.Logger.Printf("ip_geoinfo update warning: %v", err)
}
cfg.Logger.Printf("sync complete (last_id=%d -> %d)", lastID, upperID)
if err := verifyCounts(ctx, cfg, dumper, conn, upperID); err != nil {
@@ -116,3 +130,39 @@ func verifyCounts(ctx context.Context, cfg SyncConfig, dumper *Dumper, conn *pgx
}
return nil
}
func ensureIPGeoInfo(ctx context.Context, cfg SyncConfig, conn *pgx.Conn) error {
if err := EnsureIPGeoInfoTable(ctx, conn, cfg.Schema); err != nil {
return err
}
ts := time.Now().In(kst()).Format("20060102-150405")
ipListPath := filepath.Join(cfg.UpdateDir, fmt.Sprintf("public_ip_list_%s.csv", ts))
if err := ExportPublicIPs(ctx, conn, cfg.Schema, ipListPath); err != nil {
return fmt.Errorf("export public ip list: %w", err)
}
resolver, err := ResolveBackend(geo.Config{
Backend: geo.Backend(cfg.Backend),
MMDBPath: cfg.MMDBPath,
DatabaseURL: cfg.DatabaseURL,
LookupQuery: cfg.LookupQuery,
})
if err != nil {
return fmt.Errorf("init resolver for ip_geoinfo: %w", err)
}
defer resolver.Close()
sqlPath := filepath.Join(cfg.UpdateDir, fmt.Sprintf("ip_geoinfo_update-%s.sql", ts))
count, err := GenerateIPGeoInfoSQL(ctx, conn, cfg.Schema, resolver, sqlPath, true)
if err != nil {
return fmt.Errorf("generate ip_geoinfo sql: %w", err)
}
if count == 0 {
return nil
}
if err := ExecuteSQLFile(ctx, conn, sqlPath); err != nil {
return fmt.Errorf("execute ip_geoinfo sql: %w", err)
}
return nil
}

View File

@@ -20,6 +20,8 @@
- [x] 초기 적재+백필+일일 업데이트를 Go 라이브러리(`internal/userprogram`)로 통합, `user-program-sync`가 초기 CSV 임포트 후 최신 일자까지 덤프/적재하도록 리팩토링 완료: 2025-12-10 10:03 KST
- [x] 증분 기준을 created_at 날짜에서 PK(id) 기반으로 변경, 마지막 id 이후 어제까지의 최대 id까지 덤프/업서트하도록 Sync/Dump 경로 리팩토링 완료: 2025-12-10 10:20 KST
- [x] 컨테이너 사용자 UID/GID를 빌드 시 지정 가능하도록 하고 볼륨 소유권을 맞춰 권한 오류 해결 (`APP_UID`/`APP_GID`, chown 적용) 완료: 2025-12-10 10:56 KST
- [x] access log 파일 출력 + 10MB 롤링, 헤더 길이 1KB로 절단 및 프록시 IP 정보 포함 완료: 2025-12-10 12:20 KST
- [x] `ip_geoinfo` 테이블 초기/증분 upsert 자동화: sync 완료 후 public_ip 리스트를 CSV로 내보내고 신규 IP만 GeoIP 조회해 SQL 생성·실행하도록 추가 완료: 2025-12-10 12:27 KST
## 진행 예정
- [x] PostgreSQL 전용 Docker 이미지(또는 build 단계)에서 `maxminddb_fdw` 설치 후 `GeoLite2-City.mmdb` 볼륨을 `/data`로 마운트하는 `postgres` 서비스 추가 및 5432 외부 노출