Files
balikci/deploy.sh

641 lines
23 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
###############################################################################
# Oltalama Test Yönetim Paneli - Otomatik Kurulum Scripti
# Version: 1.0.0
# Date: 2025-11-10
###############################################################################
set -e # Exit on error
# Renkli çıktılar
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Değişkenler
INSTALL_DIR="/opt/oltalama"
LOG_DIR="/var/log/oltalama"
BACKUP_DIR="${INSTALL_DIR}/backups"
USER="oltalama" # Tüm sistemler için ortak kullanıcı
NODE_VERSION="20"
# Fonksiyonlar
print_header() {
echo -e "\n${BLUE}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ ║${NC}"
echo -e "${BLUE}║ Oltalama Test Yönetim Paneli - Kurulum Scripti ║${NC}"
echo -e "${BLUE}║ Version 1.0.0 ║${NC}"
echo -e "${BLUE}║ ║${NC}"
echo -e "${BLUE}╚═══════════════════════════════════════════════════════════════╝${NC}\n"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}$1${NC}"
}
print_info() {
echo -e "${BLUE} $1${NC}"
}
check_root() {
if [[ $EUID -ne 0 ]]; then
print_error "Bu script root yetkisi ile çalıştırılmalıdır."
print_info "Lütfen 'sudo ./deploy.sh' komutunu kullanın."
exit 1
fi
}
check_os() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
OS=$ID
VERSION=$VERSION_ID
print_success "İşletim sistemi tespit edildi: $PRETTY_NAME"
# Paket yöneticisi tespit et
if command -v apt-get &> /dev/null; then
PKG_MANAGER="apt"
print_info "Paket yöneticisi: APT (Debian/Ubuntu)"
elif command -v dnf &> /dev/null; then
PKG_MANAGER="dnf"
print_info "Paket yöneticisi: DNF (RedHat/Oracle/Fedora)"
elif command -v yum &> /dev/null; then
PKG_MANAGER="yum"
print_info "Paket yöneticisi: YUM (RedHat/CentOS)"
else
print_error "Desteklenen paket yöneticisi bulunamadı!"
exit 1
fi
else
print_error "İşletim sistemi tespit edilemedi!"
exit 1
fi
}
install_nodejs() {
print_info "Node.js ${NODE_VERSION}.x kuruluyor..."
if command -v node &> /dev/null; then
CURRENT_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
if [[ $CURRENT_VERSION -ge $NODE_VERSION ]]; then
print_success "Node.js $(node -v) zaten yüklü."
return
fi
fi
# NodeSource repository ekle
if [[ "$PKG_MANAGER" == "apt" ]]; then
curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash -
apt-get install -y nodejs
elif [[ "$PKG_MANAGER" == "dnf" ]] || [[ "$PKG_MANAGER" == "yum" ]]; then
curl -fsSL https://rpm.nodesource.com/setup_${NODE_VERSION}.x | bash -
$PKG_MANAGER install -y nodejs
fi
print_success "Node.js $(node -v) kuruldu."
print_success "npm $(npm -v) kuruldu."
}
install_dependencies() {
print_info "Sistem bağımlılıkları kuruluyor..."
if [[ "$PKG_MANAGER" == "apt" ]]; then
apt-get update
apt-get install -y git curl wget build-essential sqlite3
elif [[ "$PKG_MANAGER" == "dnf" ]] || [[ "$PKG_MANAGER" == "yum" ]]; then
$PKG_MANAGER update -y
# EPEL repository (bazı paketler için gerekli)
$PKG_MANAGER install -y epel-release 2>/dev/null || true
# Paketleri kur
$PKG_MANAGER install -y git curl wget gcc-c++ make sqlite
# Development tools
$PKG_MANAGER groupinstall -y "Development Tools" 2>/dev/null || true
fi
print_success "Sistem bağımlılıkları kuruldu."
}
install_pm2() {
print_info "PM2 process manager kuruluyor..."
npm install -g pm2
print_success "PM2 $(pm2 -v) kuruldu."
}
setup_directories() {
print_info "Dizinler oluşturuluyor..."
mkdir -p $LOG_DIR
mkdir -p $BACKUP_DIR
mkdir -p "${INSTALL_DIR}/backend/database"
print_success "Dizinler oluşturuldu."
}
create_user() {
print_info "Sistem kullanıcısı kontrol ediliyor..."
if id "$USER" &>/dev/null; then
print_success "Kullanıcı '$USER' zaten mevcut."
else
print_info "Kullanıcı '$USER' oluşturuluyor..."
useradd -r -s /bin/bash -d $INSTALL_DIR -m $USER
print_success "Kullanıcı '$USER' oluşturuldu."
fi
}
install_project() {
print_info "Proje dosyaları kontrol ediliyor..."
# Eğer script zaten proje dizininde çalıştırılıyorsa
if [[ -f "$(pwd)/backend/package.json" ]]; then
CURRENT_DIR=$(pwd)
print_info "Mevcut dizinden kurulum yapılıyor: $CURRENT_DIR"
if [[ "$CURRENT_DIR" != "$INSTALL_DIR" ]]; then
print_info "Dosyalar $INSTALL_DIR dizinine kopyalanıyor..."
# rsync yerine cp kullan (daha yaygın)
# Önce .git ve node_modules hariç tüm dosyaları kopyala
find "$CURRENT_DIR" -mindepth 1 -maxdepth 1 \
! -name 'node_modules' \
! -name '.git' \
! -name 'logs' \
! -name 'database' \
-exec cp -r {} "$INSTALL_DIR/" \;
print_success "Dosyalar kopyalandı."
fi
else
print_error "Proje dosyaları bulunamadı!"
print_info "Script'i proje dizininde çalıştırın veya projeyi klonlayın."
exit 1
fi
print_success "Proje dosyaları hazır."
}
install_backend() {
print_info "Backend dependencies kuruluyor..."
cd "${INSTALL_DIR}/backend"
npm install --production
print_success "Backend dependencies kuruldu."
}
install_frontend() {
print_info "Frontend dependencies kuruluyor..."
cd "${INSTALL_DIR}/frontend"
npm install
print_success "Frontend dependencies kuruldu."
}
setup_env_files() {
print_info "Çevre değişkenleri ayarlanıyor..."
# Backend .env
if [[ ! -f "${INSTALL_DIR}/backend/.env" ]]; then
cp "${INSTALL_DIR}/backend/.env.example" "${INSTALL_DIR}/backend/.env"
# Session secret oluştur
SESSION_SECRET=$(node -e "console.log(require('crypto').randomBytes(64).toString('hex'))")
# .env dosyasını güncelle
sed -i "s|NODE_ENV=development|NODE_ENV=production|g" "${INSTALL_DIR}/backend/.env"
sed -i "s|SESSION_SECRET=.*|SESSION_SECRET=${SESSION_SECRET}|g" "${INSTALL_DIR}/backend/.env"
sed -i "s|DB_PATH=.*|DB_PATH=${INSTALL_DIR}/backend/database/oltalama.db|g" "${INSTALL_DIR}/backend/.env"
print_success "Backend .env dosyası oluşturuldu."
print_warning "Gmail ve Telegram ayarlarını panelden yapabilirsiniz."
else
print_info "Backend .env dosyası zaten mevcut."
fi
# Frontend .env
if [[ ! -f "${INSTALL_DIR}/frontend/.env" ]]; then
cp "${INSTALL_DIR}/frontend/.env.example" "${INSTALL_DIR}/frontend/.env"
print_success "Frontend .env dosyası oluşturuldu."
else
print_info "Frontend .env dosyası zaten mevcut."
fi
}
setup_admin_user() {
print_info "Admin kullanıcısı oluşturuluyor..."
# Check if admin already exists
ADMIN_COUNT=$(sqlite3 "${INSTALL_DIR}/backend/database/oltalama.db" "SELECT COUNT(*) FROM admin_user;" 2>/dev/null || echo "0")
if [[ "$ADMIN_COUNT" -gt 0 ]]; then
print_info "Admin kullanıcısı zaten mevcut, atlanıyor."
return
fi
echo ""
print_warning "╔═══════════════════════════════════════════════════════════════╗"
print_warning "║ Admin Kullanıcı Bilgilerini Oluşturun ║"
print_warning "╚═══════════════════════════════════════════════════════════════╝"
echo ""
# Username
while true; do
read -p "Admin kullanıcı adı (en az 3 karakter): " ADMIN_USERNAME
if [[ ${#ADMIN_USERNAME} -ge 3 ]]; then
break
else
print_error "Kullanıcı adı en az 3 karakter olmalıdır!"
fi
done
# Password with validation
while true; do
read -sp "Admin şifresi (en az 8 karakter, harf ve rakam içermeli): " ADMIN_PASSWORD
echo ""
# Password length check
if [[ ${#ADMIN_PASSWORD} -lt 8 ]]; then
print_error "Şifre en az 8 karakter olmalıdır!"
continue
fi
# Check for letters and numbers
if ! [[ "$ADMIN_PASSWORD" =~ [a-zA-Z] ]] || ! [[ "$ADMIN_PASSWORD" =~ [0-9] ]]; then
print_error "Şifre hem harf hem de rakam içermelidir!"
continue
fi
# Confirm password
read -sp "Şifreyi tekrar girin: " ADMIN_PASSWORD_CONFIRM
echo ""
if [[ "$ADMIN_PASSWORD" == "$ADMIN_PASSWORD_CONFIRM" ]]; then
break
else
print_error "Şifreler eşleşmiyor! Tekrar deneyin."
fi
done
# Create admin user using Node.js
cd "${INSTALL_DIR}/backend"
cat > /tmp/create_admin.js << EOF
const bcrypt = require('bcrypt');
const { sequelize } = require('./src/config/database');
const AdminUser = require('./src/models/AdminUser');
(async () => {
try {
await sequelize.authenticate();
const hashedPassword = await bcrypt.hash('${ADMIN_PASSWORD}', 10);
await AdminUser.create({
username: '${ADMIN_USERNAME}',
password_hash: hashedPassword,
email: null,
full_name: 'Administrator',
});
console.log('✓ Admin kullanıcısı oluşturuldu');
process.exit(0);
} catch (error) {
console.error('✗ Hata:', error.message);
process.exit(1);
}
})();
EOF
node /tmp/create_admin.js
rm -f /tmp/create_admin.js
print_success "Admin kullanıcısı oluşturuldu: ${ADMIN_USERNAME}"
echo ""
}
setup_database() {
print_info "Database oluşturuluyor..."
cd "${INSTALL_DIR}/backend"
# Migrations
node migrations/run-migrations.js
print_success "Database migrations tamamlandı."
# Seed sample data (companies and templates only, not admin user)
ADMIN_COUNT=$(sqlite3 "${INSTALL_DIR}/backend/database/oltalama.db" "SELECT COUNT(*) FROM admin_user;" 2>/dev/null || echo "0")
if [[ "$ADMIN_COUNT" -eq 0 ]]; then
# Seed only non-admin data
cat > /tmp/seed_data.js << 'EOF'
const { sequelize } = require('./src/config/database');
const { Company, MailTemplate } = require('./src/models');
(async () => {
try {
await sequelize.authenticate();
// Seed companies
const companies = [
{ name: 'Türk Telekom', domain: 'turktelekom.com.tr', description: 'Türkiye\'nin lider telekomünikasyon şirketi' },
{ name: 'İş Bankası', domain: 'isbank.com.tr', description: 'Türkiye\'nin en büyük özel sermayeli bankası' },
{ name: 'PTT', domain: 'ptt.gov.tr', description: 'Posta ve Telgraf Teşkilatı' },
];
for (const company of companies) {
await Company.findOrCreate({ where: { name: company.name }, defaults: company });
}
// Seed templates
const templates = [
{
name: 'Banka Güvenlik Uyarısı',
template_type: 'bank',
subject_template: '🔒 {{company_name}} - Hesap Güvenlik Uyarısı',
body_html: '<html><body style="font-family: Arial, sans-serif; line-height: 1.6;"><div style="max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #ddd;"><h2 style="color: #d32f2f;">🔒 Güvenlik Uyarısı</h2><p>Sayın {{employee_name}},</p><p>{{company_name}} hesabınızda şüpheli bir aktivite tespit edildi. Hesabınızın güvenliğini sağlamak için lütfen aşağıdaki bağlantıya tıklayarak kimlik doğrulaması yapın.</p><p style="text-align: center; margin: 30px 0;"><a href="{{tracking_url}}" style="background-color: #d32f2f; color: white; padding: 12px 30px; text-decoration: none; border-radius: 5px; display: inline-block;">Hesabımı Doğrula</a></p><p style="color: #666; font-size: 12px;">Bu işlemi 24 saat içinde yapmazsanız hesabınız geçici olarak askıya alınabilir.</p><p style="color: #666; font-size: 12px;">Tarih: {{current_date}}</p><hr style="border: none; border-top: 1px solid #eee; margin: 20px 0;"><p style="color: #999; font-size: 11px;">Bu bir phishing testidir. Gerçek bir güvenlik tehdidi değildir.</p></div></body></html>',
description: 'Banka hesap güvenliği temalı phishing test maili',
active: true,
},
{
name: 'E-Devlet Sistem Güncellemesi',
template_type: 'edevlet',
subject_template: '⚠️ E-Devlet - Sistem Güncellemesi Gerekli',
body_html: '<html><body style="font-family: Arial, sans-serif; line-height: 1.6;"><div style="max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #ddd;"><div style="background-color: #c62828; color: white; padding: 15px; text-align: center;"><h2 style="margin: 0;">E-DEVLET KAPISI</h2></div><div style="padding: 20px;"><p>Sayın {{employee_name}},</p><p>E-Devlet sistemimizde önemli bir güvenlik güncellemesi yapılmaktadır. Hesabınıza erişiminizi sürdürebilmek için lütfen kimlik bilgilerinizi güncelleyin.</p><p style="text-align: center; margin: 30px 0;"><a href="{{tracking_url}}" style="background-color: #c62828; color: white; padding: 12px 30px; text-decoration: none; border-radius: 5px; display: inline-block;">Bilgilerimi Güncelle</a></p><p style="background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 10px; color: #856404;">⚠️ Bu işlemi 48 saat içinde tamamlamazsanız E-Devlet hesabınız askıya alınacaktır.</p><p style="color: #666; font-size: 12px;">İşlem Tarihi: {{current_date}}</p></div><div style="background-color: #f5f5f5; padding: 15px; text-align: center; color: #666; font-size: 11px;"><p>Bu bir phishing farkındalık testidir.</p><p>© {{current_year}} E-Devlet Kapısı</p></div></div></body></html>',
description: 'E-Devlet sistem güncellemesi temalı phishing test maili',
active: true,
},
];
for (const template of templates) {
await MailTemplate.findOrCreate({ where: { template_type: template.template_type }, defaults: template });
}
console.log('✓ Örnek veriler oluşturuldu');
process.exit(0);
} catch (error) {
console.error('✗ Hata:', error.message);
process.exit(1);
}
})();
EOF
node /tmp/seed_data.js
rm -f /tmp/seed_data.js
print_success "Örnek veriler oluşturuldu (şirketler ve mail şablonları)."
else
print_info "Database zaten veri içeriyor, seed atlanıyor."
fi
}
build_frontend() {
print_info "Frontend build ediliyor..."
cd "${INSTALL_DIR}/frontend"
npm run build
print_success "Frontend build tamamlandı."
}
setup_pm2() {
print_info "PM2 konfigürasyonu yapılıyor..."
# ecosystem.config.js oluştur
cat > "${INSTALL_DIR}/ecosystem.config.js" << 'EOF'
module.exports = {
apps: [
{
name: 'oltalama-backend',
cwd: '/opt/oltalama/backend',
script: 'src/app.js',
instances: 1,
exec_mode: 'cluster',
watch: false,
max_memory_restart: '500M',
env: {
NODE_ENV: 'production',
PORT: 3000,
},
error_file: '/var/log/oltalama/backend-error.log',
out_file: '/var/log/oltalama/backend-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
},
{
name: 'oltalama-frontend',
cwd: '/opt/oltalama/frontend',
script: 'npm',
args: 'run preview',
instances: 1,
exec_mode: 'fork',
watch: false,
max_memory_restart: '300M',
env: {
NODE_ENV: 'production',
PORT: 4173,
},
error_file: '/var/log/oltalama/frontend-error.log',
out_file: '/var/log/oltalama/frontend-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
},
],
};
EOF
print_success "PM2 konfigürasyon dosyası oluşturuldu."
}
start_services() {
print_info "Servisler başlatılıyor..."
cd "${INSTALL_DIR}"
# PM2 ile başlat
pm2 start ecosystem.config.js
# Startup script oluştur
pm2 startup systemd -u root --hp /root
pm2 save
print_success "Servisler başlatıldı."
# Durum göster
sleep 2
pm2 status
}
setup_permissions() {
print_info "Dosya izinleri ayarlanıyor..."
# Dizin sahipliği
chown -R ${USER}:${USER} ${INSTALL_DIR}
chown -R ${USER}:${USER} ${LOG_DIR}
# .env dosyaları
chmod 600 "${INSTALL_DIR}/backend/.env"
chmod 600 "${INSTALL_DIR}/frontend/.env"
# Database
chmod 600 "${INSTALL_DIR}/backend/database/oltalama.db"
print_success "Dosya izinleri ayarlandı."
}
setup_firewall() {
print_info "Firewall ayarlanıyor..."
if command -v ufw &> /dev/null; then
# Ubuntu/Debian - UFW
print_info "UFW kullanılıyor..."
# SSH izin ver
ufw allow 22/tcp comment 'SSH'
# HTTP/HTTPS izin ver
ufw allow 80/tcp comment 'HTTP'
ufw allow 443/tcp comment 'HTTPS'
# Backend ve Frontend portlarını engelle (sadece localhost'tan erişilebilir)
ufw deny 3000/tcp comment 'Oltalama Backend (use reverse proxy)'
ufw deny 4173/tcp comment 'Oltalama Frontend (use reverse proxy)'
# UFW'yi aktifleştir (sadece henüz aktif değilse)
if ! ufw status | grep -q "Status: active"; then
print_warning "UFW firewall aktifleştiriliyor..."
print_warning "SSH bağlantınız kopmayacak (port 22 açık)."
read -p "Devam etmek için ENTER'a basın..."
echo "y" | ufw enable
fi
print_success "Firewall ayarlandı (UFW)."
elif command -v firewall-cmd &> /dev/null; then
# RedHat/Oracle/CentOS - firewalld
print_info "firewalld kullanılıyor..."
# firewalld'yi başlat ve aktifleştir
systemctl start firewalld 2>/dev/null || true
systemctl enable firewalld 2>/dev/null || true
# HTTP/HTTPS izin ver
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=ssh
# Backend ve Frontend portları sadece localhost'tan erişilebilir
# (reverse proxy kullanılacağı için dışarıdan erişim kapalı)
# Yeniden yükle
firewall-cmd --reload
print_success "Firewall ayarlandı (firewalld)."
else
print_warning "Firewall bulunamadı, firewall ayarları atlanıyor."
print_warning "Güvenlik için manuel olarak firewall yapılandırmanız önerilir."
fi
}
setup_backup_cron() {
print_info "Otomatik yedekleme ayarlanıyor..."
# Backup script oluştur
cat > "${INSTALL_DIR}/backup.sh" << 'EOF'
#!/bin/bash
BACKUP_DIR="/opt/oltalama/backups"
DB_PATH="/opt/oltalama/backend/database/oltalama.db"
DATE=$(date +%Y%m%d-%H%M%S)
mkdir -p $BACKUP_DIR
cp $DB_PATH "$BACKUP_DIR/oltalama-$DATE.db"
find $BACKUP_DIR -name "oltalama-*.db" -mtime +30 -delete
echo "Backup completed: oltalama-$DATE.db"
EOF
chmod +x "${INSTALL_DIR}/backup.sh"
# Crontab ekle
CRON_JOB="0 3 * * * ${INSTALL_DIR}/backup.sh >> ${LOG_DIR}/backup.log 2>&1"
(crontab -l 2>/dev/null | grep -v "backup.sh"; echo "$CRON_JOB") | crontab -
print_success "Otomatik yedekleme ayarlandı (her gün saat 03:00)."
}
print_completion() {
echo -e "\n${GREEN}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ ║${NC}"
echo -e "${GREEN}║ 🎉 Kurulum Tamamlandı! 🎉 ║${NC}"
echo -e "${GREEN}║ ║${NC}"
echo -e "${GREEN}╚═══════════════════════════════════════════════════════════════╝${NC}\n"
print_info "Servis Bilgileri:"
echo -e " Backend: ${BLUE}http://localhost:3000${NC}"
echo -e " Frontend: ${BLUE}http://localhost:4173${NC}"
print_info "\nAdmin Hesabı:"
echo -e " ${GREEN}${NC} Kurulum sırasında oluşturuldu"
echo -e " ${GREEN}${NC} Güvenli şifre kullanıldı"
print_info "\nYapılması Gerekenler:"
echo " 1. Nginx Proxy Manager'da reverse proxy ayarları yapın"
echo " 2. Frontend için: yourdomain.com → localhost:4173"
echo " 3. Backend API için path: /api → localhost:3000"
echo " 4. SSL sertifikası ekleyin"
echo " 5. Panele giriş yapın ve Gmail/Telegram ayarlarını yapın"
print_info "\nYararlı Komutlar:"
echo " Servis durumu: pm2 status"
echo " Logları izle: pm2 logs"
echo " Servis yeniden başlat: pm2 restart all"
echo " Servis durdur: pm2 stop all"
print_info "\nDokümantasyon:"
echo " Detaylı kurulum kılavuzu: ${INSTALL_DIR}/DEPLOYMENT.md"
echo " Kullanım kılavuzu: ${INSTALL_DIR}/KULLANIM.md"
echo " Hızlı başlangıç: ${INSTALL_DIR}/QUICKSTART.md"
print_success "\nKurulum başarıyla tamamlandı!"
}
# Ana kurulum fonksiyonu
main() {
print_header
check_root
check_os
print_info "Kurulum başlıyor...\n"
install_dependencies
install_nodejs
install_pm2
create_user
setup_directories
install_project
install_backend
install_frontend
setup_env_files
setup_database
setup_admin_user
build_frontend
setup_pm2
setup_permissions
start_services
setup_firewall
setup_backup_cron
print_completion
}
# Script'i çalıştır
main "$@"